delphi 7 中封装DLL问题
封装DLL的时候,下面的这个方法,当返回来的值太大的时候报错。
function get_aa(str: PWideChar): pAnsiChar; stdcall;
var
rets :AnsiString;
begin
rets:=Soap.get_bb(str) ;
result:= pAnsiChar(rets);
end;
返回来的 大于 3000行记录的时候 就报错了。之前用 PWideChar 的时候 返回来大于100行记录就报错了
function get_aa(str: PWideChar): PWideChar; stdcall;
var
rets :wideString;
begin
rets:=Soap.get_bb(str) ;
result:= pAnsiChar(rets);
end;
所有我觉得还是这个 字符串大小的问题,delphi 7 中怎么声明更加大的字符传类型呢?
[解决办法]
这种函数写法有问题.
rets变量在离开函数的时候就会被销毁.你返回指向它当时所占的内存的指针,这块内存是内存管理器中被回收待重复利用的.
内容没错那是因为刚好这块内存没有被重复利用到.
function get_aa(str: PWideChar): pAnsiChar; stdcall;
var
rets :AnsiString;
begin
rets:=Soap.get_bb(str) ;
result:= coTaskMemAlloc(Length(rets));
move(PAnsiChar(rets)^, Result^, Length(rets));
end;
记得调用方调用完毕后coTaskmemFree把内存释放掉.
这样你的DLL导出函数C++/Delphi都能用.
[解决办法]
多一指去接收就好啦
[解决办法]
设计上存在漏洞,DLL 返回不定长内容时,应该用参数传入缓冲区及其大小,
将返回数据放到缓冲区中,并同时返回数据实际大小。
如果传入的大小是0,则计算所需空间的大小并返回,调用方根据大小分配好空间再次调用即可。
这种用法太经典了!
[解决办法]
uses
ActiveX;
[解决办法]
支持10楼。这样不浪费内存,也合理,只是都走了一两步。
[解决办法]
大概是这样的
function get_aa(str: PWideChar; buffer :pAnsiChar; var size:Integer):Integer; stdcall;
var
rets :AnsiString;
begin
rets := Soap.get_bb(str) ;
if Length(rets)<size then
begin
lstrcpyn(buffer, pchar(rets), size);
size := Length(rets);
Result := S_OK;
end
else
begin
if size=0 then
size := Length(rets)
else
size := 0;
Result := S_FALSE;
end;
end;
[解决办法]
D7有PWideChar类型?
#14楼的代码
rets明明是AnsiString类型,你却写了这句pchar(rets),你如果有PWideChar类型,那么PChar应该默认是PWideChar,那么这句就等价于 PWideChar(rets),而此时的rets是AnsiString....