读书人

DLL动态数组的生命周期?该怎么解决

发布时间: 2012-11-06 14:07:00 作者: rapoo

DLL动态数组的生命周期?
我在DLL中返回一个动态数组,比如
procedure fun(var arr: tarr of Tmyrec);

数组长度是在函数中通过setlength来设定的

我的问题是,这个数组的生命周期是到什么时候??

我发这个问题是担心函数返回后,这段内存会被delphi回收导致exe中接受的数据错误
exe可能是任何语言,不仅限于delphi
那么通过这种方式返回数据,是否安全?

[解决办法]
不安全,delphi和其他语言动态数组机制不同,可能会导致结果错误,你可以试试指针数组,虽然比较麻烦,但却是全windows通用的
[解决办法]
如果担心回收,就把返回的数组再次存入到你可以控制生命周期的数组中就可以了。
[解决办法]

探讨

引用:

如果担心回收,就把返回的数组再次存入到你可以控制生命周期的数组中就可以了。

嗯,这个知道。但我想知道的是 是不是函数返回了,delphi就认为该指针可以回收了?
如果是的话,那也就是说exe中从这个函数所获取的指针已经是不安全的了?

[解决办法]
Caller中第1种情况
procedure xxx;
var
arr: tarr of Tmyrec;
begin
DLLFun(arr); //DLL申请数组的内存,xxx只提供一个指针地址给,DLLFun中填一个地址到arr上
end;//这里会释放本过程中的自动管理内存的变量,如String,Array,Variant等
释放一个在DLL中申请的内存,在都没有引用ShareMem.pas的情况下,要异常/溢出.

Caller中第2种情况
var
arr: tarr of Tmyrec;//全局变量
procedure xxx;
begin
DLLFun(arr); //DLL申请数组的内存,xxx只提供一个指针地址,DLLFun中填一个地址到arr上
end;//这里不会执行任何关于arr的操作
这种情况下,arr变量的内存会一直存在,直到进程结束.如果始终保证同一个DLL执行SetLength,而且只在这个DLL中SetLength(多次执行/不同的函数中执行都一样)就不会导致内存泄露,而且arr也能正常使用
但是:如果中途释放了DLL(FreeLibrary),那这个arr指针指向的内存将变得不确定(随着DLL释放而释放),如果Exe和DLL或者其他DLL都有对这个array的SetLength,是不正确的,异常.
如果都引用了ShareMem.pas除外.

正确的作法:
Exe中申请内存,DLL填值,并返回填了多少个值
procedure xxx;
var
arr: tarr of Tmyrec;
Count : integer;
begin
SetLength(arr, MaxCount);
Count := DLLFun(arr);//由于array同时具有长度,所以这里不需要传MaxCount进去了
for i:=0 to Count-1 do ...
end;

[解决办法]
这种还是EXE中申请空间,DLL只是读写这个空间的为好,一般程序应该遵循谁申请谁释放这样比较好
[解决办法]
动态数组是自动管理的,不用特意的去释放,提前释放设置为nil就行了,即arr:=nil;

读书人网 >.NET

热点推荐