我最近在一个系统中这样使用Interface:
1、ICustomAddin 接口名称
2、TCustomAddin 继承自TInterfaceObject,并实现了ICustomAddin接口
3、在DLL中使用一个函数返回该接口
4、主程序中会用动态调用DLL,取得接口后调用接口的方法进行工作,有下列几种使用情况:
4.1、在一个过程中取得接口并赋值给局域变量,使用完后赋值为nil——释放。
4.2、在一个线程中取得接口并赋值给线程属性变量,使用完后赋值为nil——释放。然后线程结束。主线程会使用该线程取得的接口进行操作(设置Addin终止标记)
现在的问题是:
4.1能够正确执行,多次执行都没有问题!但是4.2执行到退出线程处理函数时发生错误( EAccessViolation),错误发生在_IntfClear调用中。注意,并不是退出Execute而是Execute中的一个方法,这个方法使用了接口。
请教各位富翁帮助选找问题,多谢!
说明:
在这个多线程系统中不存在线程安全和访问冲突问题,对这一点我有充分的信心!
1、ICustomAddin 接口名称
2、TCustomAddin 继承自TInterfaceObject,并实现了ICustomAddin接口
3、在DLL中使用一个函数返回该接口
4、主程序中会用动态调用DLL,取得接口后调用接口的方法进行工作,有下列几种使用情况:
4.1、在一个过程中取得接口并赋值给局域变量,使用完后赋值为nil——释放。
4.2、在一个线程中取得接口并赋值给线程属性变量,使用完后赋值为nil——释放。然后线程结束。主线程会使用该线程取得的接口进行操作(设置Addin终止标记)
现在的问题是:
4.1能够正确执行,多次执行都没有问题!但是4.2执行到退出线程处理函数时发生错误( EAccessViolation),错误发生在_IntfClear调用中。注意,并不是退出Execute而是Execute中的一个方法,这个方法使用了接口。
请教各位富翁帮助选找问题,多谢!
说明:
在这个多线程系统中不存在线程安全和访问冲突问题,对这一点我有充分的信心!
解决方案 »
- 两进程间使用PostMessage发送字符串,接收出错询求帮助。
- 如何删除Windows目录下的指定文件
- 请问activemovie的用法?菜鸟问题
- 我用Delphi想做关于数据库(Oracle)的Web应用,查了下资料,WebBroker,Websnap,IntraWeb都可以实现,不知用什么好?哪位能详细说明一下
- 与大家讨论一个是否值得使用第三方控件的问题,来者有分,分我多的是。
- 有检查Delphi程序内存泄漏的工具吗?
- 关于ado的问题。
- 求救,delphi7安装完毕退出时报错
- 各位老大,help me ! 100分急求表达式算法!!!
- 金山词霸道效果
- 如何获取报表总共页数?
- 有谁知道QQ的流程???? 以及QQ中运用的数据库模型是什么?
1 对象被释放后但对象被继续引用
2 对象未被创建便被引用
3 指针未初始化再仔细检查一下代码,必要时加Assigned()检查指针是否合法
按照delphi的内存管理,如果你的一个类实现了某个接口,那么每调用一次接口中的方法,在接口内部其实实现了
_AddRef
IntefaceMethod
_ReleaseRef
一旦接口的引用计数为0,接口将自动释放,并不需要手工释放。
假如你的接口是被你定义的线程实现,那么在线程终止的时候,其相应创建的接口也将被释放
1、在DLL中的类里实现接口,利用一个输出函数创建对象并返回接口:GetAddinIntface:ICustomAddin。
2、主线程有各线程队列创建、管理制定数目的线程进行工作,这些
线程从任务队列中取得任务并调用DLL返回的接口进行处理,主线程会
通过接口(DLL返回的)对Addin设置终止标记,以便中途终止任务的处理。
---Load DLL
Try
1 AddinIntf{属性,有读些方法,防止访问冲突} := GetAddinIntf;
2 try
3 AddinIntf.ProcTask(Params);
4 finally
5 AddinIntf:=nil;退出引用
6 end;
finally
----UnLoad DLL
end;
说明主线程使用是通过手工操作的,且使用了Assigned(AddinIntf)。
错误发生在过程退出时,我将Load/Uload DLL块内的代码移到一个过程内,
然后在这里调用线的过程问题就解决了。
5 是释放了接口的,我跟踪到System中看过了,关键是在函数尾时有什么原因
导致的再次释放接口?因为在函数退出前我就Unload DLL 了,当然会有空地址操
作了!
虽然问题暂时解决了,但百思不得其解,毕竟不合逻辑!
而且我事用下面的方法调用也不会出错:
function CheckAddin: Boolean;
var
lIntf : ICustomAddin;
begin
--LoadLibrary(FileName);
try
lIntf := GetAddinIntf;取得接口
try
Result := Assigned(lIntf);
if Result then
begin
lCode := StrToIntDef(lIntf.GetProperty('Code'), 0);
lVersion := StrToIntDef(lIntf.GetProperty('Version'), 0);
end;
finally
lIntf := nil;
end;
except
Result := False;
end;
--FreeLibrary(DLLHandle)
end;