delphi 7 中封装DLL问题

h_flys 2013-08-15 05:35:36
封装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 中怎么声明更加大的字符传类型呢?

...全文
361 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
h_flys 2013-08-22
  • 打赏
  • 举报
回复
D7 确实已经有 PWideChar类型 了。。。。。
一如当初 2013-08-21
  • 打赏
  • 举报
回复
D7有PWideChar类型? #14楼的代码 rets明明是AnsiString类型,你却写了这句pchar(rets),你如果有PWideChar类型,那么PChar应该默认是PWideChar,那么这句就等价于 PWideChar(rets),而此时的rets是AnsiString....
TheMadMan 2013-08-19
  • 打赏
  • 举报
回复
支持10楼。这样不浪费内存,也合理,只是都走了一两步。
tcmakebest 2013-08-19
  • 打赏
  • 举报
回复
大概是这样的
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;
tcmakebest 2013-08-17
  • 打赏
  • 举报
回复
设计上存在漏洞,DLL 返回不定长内容时,应该用参数传入缓冲区及其大小, 将返回数据放到缓冲区中,并同时返回数据实际大小。 如果传入的大小是0,则计算所需空间的大小并返回,调用方根据大小分配好空间再次调用即可。 这种用法太经典了!
武稀松 2013-08-17
  • 打赏
  • 举报
回复
引用 7 楼 h_flys 的回复:
用 result:= coTaskMemAlloc(Length(rets)); 后编译报 Undeclared identifier:'coTaskMemAlloc' 错误啊。 请指导。。。
uses ActiveX;
h_flys 2013-08-17
  • 打赏
  • 举报
回复
引用 10 楼 tcmakebest 的回复:
设计上存在漏洞,DLL 返回不定长内容时,应该用参数传入缓冲区及其大小, 将返回数据放到缓冲区中,并同时返回数据实际大小。 如果传入的大小是0,则计算所需空间的大小并返回,调用方根据大小分配好空间再次调用即可。 这种用法太经典了!
刚接触 delphi 不久,能否给个例子啊。。。。这样说我不太明白啊。。
武稀松 2013-08-16
  • 打赏
  • 举报
回复
这种函数写法有问题. 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都能用.
h_flys 2013-08-16
  • 打赏
  • 举报
回复
引用 8 楼 wj150158472 的回复:
多傳一個指針進來去接收數據就好啦
怎么 写呢?
h_flys 2013-08-16
  • 打赏
  • 举报
回复
就是定义一个 出参,封装一下成 DLL 而已啊。。。
h_flys 2013-08-16
  • 打赏
  • 举报
回复
现在的记录 大概是 2万行啊。。。。返不回来啊。。。。 请指教啊。。
屌絲來襲 2013-08-16
  • 打赏
  • 举报
回复
多傳一個指針進來去接收數據就好啦
h_flys 2013-08-16
  • 打赏
  • 举报
回复
用 result:= coTaskMemAlloc(Length(rets)); 后编译报 Undeclared identifier:'coTaskMemAlloc' 错误啊。 请指导。。。
sololie 2013-08-15
  • 打赏
  • 举报
回复
这代码真是乱来嘛,楼下解释
LastAvengers 2013-08-15
  • 打赏
  • 举报
回复
那就继续用Pchar
threenewbee 2013-08-15
  • 打赏
  • 举报
回复
delphi的问题请去编程语言/框架中的delphi板块提问。 自己可以移贴过去。

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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