线程中调用DLL,长时间运行出先问题。

huboy 2013-06-09 11:36:31
平台: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;
...全文
306 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
xhz8000 2013-06-15
  • 打赏
  • 举报
回复
orderstring离开函数已经被销毁,你还返回PChar(orderstring)。这个是个隐患。 楼主一直不重视这个! 呵呵。
ZyxIp 2013-06-14
  • 打赏
  • 举报
回复
觉得还要直接返回PCHAR,而是由调用者分配,传递进去,只返回结果的长度就好。
武稀松 2013-06-14
  • 打赏
  • 举报
回复
orderstring离开函数已经被销毁,你还返回PChar(orderstring)。这个是个隐患。
huboy 2013-06-14
  • 打赏
  • 举报
回复
感谢feiba7288..连续运行几天,还没出现过错误,继续观察中。。应该是这个强制转换的问题。
sololie 2013-06-10
  • 打赏
  • 举报
回复
把CreateOrder写在dll外直接线程调用做测试,记得写日志记录上下文信息,然后去睡觉吧,明天看日志
sololie 2013-06-10
  • 打赏
  • 举报
回复
取到的dll中CreateOrder函数地址为0,调用地址0就报AC错误了,1,2小时才出错,得看你线程的创建代码和线程执行的代码。 另外你可以把CreateOrder写在dll外再做下测试。
huboy 2013-06-10
  • 打赏
  • 举报
回复
忘了说了。将DLL中函数CreateOrder直接写到EXE主程序中不会出错。已经连续运行3天,开了几台机器做测试,现在测试中,几乎每一步都做了LOG输出。
feiba7288 2013-06-10
  • 打赏
  • 举报
回复
忘记还要将StrCopy(orderstring, PChar(inttohex(order[i], 2)));改为SysUtils.StrCat(orderstring, PChar(inttohex(order[i], 2)));
xhz8000 2013-06-10
  • 打赏
  • 举报
回复
首先很明显是个错误! Result := PChar(orderstring); 觉得在调用分方配内存给被用方使用才是好办法! 另一个就是完全又被调用方管理内存,也就是分配和释放都有DLL来完成;
feiba7288 2013-06-10
  • 打赏
  • 举报
回复
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;
feiba7288 2013-06-10
  • 打赏
  • 举报
回复
修改为下面代码试下,我觉得问题出在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;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧