读书人

线程中调用DLL长时间运行出先有关问

发布时间: 2013-08-09 15:16:24 作者: rapoo

线程中调用DLL,长时间运行出先问题。
平台:Windows 7 + Delphi 7
现象:主程序创建N个线程(>50),每个线程都会调用同一个DLL,线程内部为循环运行(除非Teiminate),大约1,2小时后开始报错。


主程序相关代码(仅示例代码,主程序及DLL均第一个单元引用FASTMM):

TCreateOrder = function(DeviceID:PChar): PChar; stdcall;


procedure
var

Func: TCreateOrder;
t_dll:Cardinal;
begin

@Func := GetProcAddress(t_dll, 'CreateOrder'); //t_dll为exe建立时Load,,尝试过每次Load,问题依旧
cmdSend := Func(PChar(tcomid));
//这里即为出错位置。Access violation at address 0C708563 in module 'ys.dll'. Write of address 00000000 In TThreadCJ
end;


DLL代码:

function CreateOrder(DeviceID:PChar): PChar;stdcall;
var
order:array[0..6] of integer;
i:integer;
orderstring:string;
CommID:integer;
begin
try
CommID := strtoint(DeviceID);
order[0]:= CommID mod 200;
order[1]:= commid div 200;
order[2]:= 3;
order[3]:= 0;
order[4]:= 0;
order[5]:= 0;
order[6]:= 0;
orderstring := '';
for i:= 0 to 6 do
begin
orderstring := orderstring + inttohex(order[i],2) + ' ';
end;
Result := PChar(orderstring);
except on e:exception do
begin
//
end;
end;
end;

exports
CreateOrder;


[解决办法]
修改为下面代码试下,我觉得问题出在dll函数中强制将String的变量转为PCHar作为返回值上(Result := PChar(orderstring);)

function CreateOrder(DeviceID:PChar): PChar;stdcall;
var
order:array[0..6] of integer;
i:integer;
orderstring:PChar;//orderstring:string;
CommID:integer;
begin
try
CommID := strtoint(DeviceID);
order[0]:= CommID mod 200;
order[1]:= commid div 200;
order[2]:= 3;
order[3]:= 0;
order[4]:= 0;
order[5]:= 0;
order[6]:= 0;
{orderstring := '';
for i:= 0 to 6 do
begin
orderstring := orderstring + inttohex(order[i],2) + ' ';
end;
Result := PChar(orderstring);}
GetMem(orderstring, 7*2+1);
try
for i:= 0 to 6 do
StrCopy(orderstring, PChar(inttohex(order[i], 2)));
Result := orderstring;
finally
FreeMem(orderstring);
end;
except on e:exception do
begin
//
end;
end;
end;
[解决办法]
function CreateOrder(DeviceID:PChar): PChar;stdcall;
var
order:array[0..6] of integer;
i:integer;
orderstring:PChar;//orderstring:string;
CommID:integer;
begin
try
CommID := strtoint(DeviceID);
order[0]:= CommID mod 200;
order[1]:= commid div 200;
order[2]:= 3;
order[3]:= 0;
order[4]:= 0;
order[5]:= 0;
order[6]:= 0;
{orderstring := '';
for i:= 0 to 6 do


begin
orderstring := orderstring + inttohex(order[i],2) + ' ';
end;
Result := PChar(orderstring);}
GetMem(orderstring, 7*2+1);
try
for i:= 0 to 6 do
StrCopy(orderstring, PChar(inttohex(order[i], 2)));
Result := orderstring;
finally
FreeMem(orderstring);
end;
except on e:exception do
begin
//
end;
end;
end;
[解决办法]
首先很明显是个错误! Result := PChar(orderstring);

觉得在调用分方配内存给被用方使用才是好办法!

另一个就是完全又被调用方管理内存,也就是分配和释放都有DLL来完成;

[解决办法]
忘记还要将StrCopy(orderstring, PChar(inttohex(order[i], 2)));改为SysUtils.StrCat(orderstring, PChar(inttohex(order[i], 2)));
[解决办法]
orderstring离开函数已经被销毁,你还返回PChar(orderstring)。这个是个隐患。
[解决办法]
觉得还要直接返回PCHAR,而是由调用者分配,传递进去,只返回结果的长度就好。
[解决办法]
orderstring离开函数已经被销毁,你还返回PChar(orderstring)。这个是个隐患。

楼主一直不重视这个! 呵呵。

读书人网 >.NET

热点推荐