同样代码在DLL和在程序中执行,报内存错误(50分)

  • 主题发起人 主题发起人 kendingxing
  • 开始时间 开始时间
K

kendingxing

Unregistered / Unconfirmed
GUEST, unregistred user!
在DLL里:
function GetDevState(var state:PChar):integer;stdcall; //取端口状态
var
rData : TGetDevStateArray ;
dwRet,dwLen,k,l: DWORD ;
p:pchar;
s:string;
begin
Result:=0;
try
dwLen := XC_MAX_PORT_NUM * 2 ;
dwRet := XC_GetDevState( rData , @dwLen ) ;//调用其他DLL
if dwRet<> XCR_OK then
begin
Result:=1;
Exit;
end
else
p:= rData;
s:=copy(p,1,8);
state:=pchar(s);
Result:=0;
except
Result:=0;
end;
end;

在程序中直接执行这段代码:
procedure TForm1.Button3Click(Sender: TObject);
var
rData : TGetDevStateArray ;
dwRet,dwLen,k,l: DWORD ;
p:pchar;
s:string;
begin
try
dwLen := XC_MAX_PORT_NUM * 2 ;
dwRet := XC_GetDevState( rData , @dwLen ) ;
if dwRet<> XCR_OK then
begin
Exit;
end
else
p:= rData;
s:=copy(p,1,8);
memo1.lines.Add(s);
except
end;
end;

如果写在DLL里再调用会出现内存地址错误;
但在程序中直接执行则没有这个错误

内存释放问题还是别的?谢谢
 
var state:PChar
state:=pchar(s);
不要这样传,你这样会造成内存分配/释放不正常
应该用state:pchar,并在exe中分配空间,然后在DLL中用CopyMemory把内容写进去
 
我知道有一种情况在程序中执行没有问题,但是DLL中报错,uses中引使的单元不全,例如DLL中封装数据库,在调用时没有引用数据库单元,就会有内存错误,反之也是一样,检查一下!
 
怎么写,帮我写一下,真不懂
 
var state:PChar var不要??
 
我加sharemem了

对“轻舞肥羊”说:
你说的那个能简单写一下吗?
刚接触这些,真不懂,谢谢了
 
你使用state:=pchar(s);
把State传回给EXE是不行的.
String是生存期自管理的.当离开DLL中的函数的时候局部变量字符串s已经被释放掉了.你的state指向的就是无效的内存地址.
你可以模仿一些API,例如GetWindowText,在EXE中分配好内存.传递一个地址,和一个长度进去.在DLL中把数据拷贝到EXE传入的内存块中就行了.这样做符合在那边分配就在那边释放的原则.
function GetDevState(state:PChar; Len : Integer):integer;stdcall;
begin
......
CopyMemory(PChar(s), state, Length(s));//要检查下s的长度有没有超过Len
end;
调用时
state : string;
.....
setlength(state, $FF);
GetDevState(PChar(state), $FF);


诸如此类
 
在EXE中:
var state: PChar;
GetMem(state, 长度...);
GetDevState(state):
FreeMen(state);
必须保证长度足够,否则还是会出错
 
后退
顶部