怎么才算是正确写法?(200分)

  • 主题发起人 主题发起人 onedot
  • 开始时间 开始时间
O

onedot

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个函数是调用第三方的DLL文件,里面一个函数接受2个参数,其中1个是返回参数<br>还有一个返回值。它们都是字符型。考虑到通用,都使用PCHAR来调用(PWINDCHAR也许更好)<br>在DELPHI里定义函数如下<br>Function my_call(const ASend :pchar,var AReturn:pchar):Pchar;stdcall;<br>.....<br><br>但我在一个地方调用这个函数怎么写才是对的?<br>procedure TForm1.Call;<br>var Lsend,LReturn,LResult:pchar,<br>begin<br>&nbsp; GetMem(Lsend,512);<br>&nbsp; GetMem(Lsend,512);<br>&nbsp; GetMem(Lsend,512);<br>&nbsp; ....//给Lsend一个初始值<br>&nbsp; ....<br>&nbsp; LResult:=My_call(LSend,LReturn);<br>&nbsp; FreeMem(LSend);<br>&nbsp; FreeMem(LReturn);<br>&nbsp; FreeMrm(LResult): &nbsp; &nbsp;<br>end;<br>为什么老是在FREEMEM时会出错,如果不做FREEMEM也出错,但如果不调用那个函数,倒是没错误<br>但为什么我调用了后就不能对这些PCHAR做FREEMEM?奇怪的是如果我调用这个函数,哪怕是<br>在Freemem(LSend)前做Freemem任何一个和该函数无关的PCHAR变量都会出错!<br><br>但如果是:<br>var Lsend,LReturn,LResult:pchar,<br>begin<br>&nbsp; &nbsp;Lsend;=pchar(Astr);<br>&nbsp; &nbsp;LReturn:=pchar(AReturn); &nbsp;....//给Lsend,LReturn一个初始值<br>&nbsp; &nbsp;AResult:=My_call(LSend,LReturn);<br>&nbsp; &nbsp;//AResult,Astr,AReturn都是字符串变量<br>end; <br><br>这样是不会出错,我知道DELPHI里字符串的资源是系统自动释放的<br>所以这些地方对那些PCHAR不用FREEMEM<br>但我还是不放心我写的是否会造成资源有被泄露的??<br>那么全部使用PCHAR直接写该怎么写?<br><br><br><br>
 
我一般都是用的string来做的<br>你的这段代码有问题吧!<br>GetMem(Lsend,512);<br>GetMem(Lsend,512);<br>GetMem(Lsend,512);<br>
 
faint//拷贝错<br><br>&nbsp; GetMem(Lsend,512);<br>&nbsp; GetMem(LReturn,512);<br>&nbsp; GetMem(LResult,512);<br><br>//很多dll如果STRING调用出错<br>
 
试一下不要给LReturn 和 LResult分配内存
 
但我看DELPHI里的代码都是自己创建,自己分配,自己释放<br>是不是我的分配大小不对才会出错?
 
问题可能是你虽然给LReturn 分配了内存,可是你将它以变参形式传进了my_call,<br>在my_call中又将LReturn指向了另一块内存,原先的就丢了;LResult也是差不多<br>道理。<br><br>所以建议你先试试不要给LReturn 和 LResult分配内存,当然也不要释放。<br>
 
你对比一下调用My_call()前后对Lsend,LReturn,LResult的指针值有什么变化!还可以<br>sizeof()函数看看Lsend,LReturn,LResult在getmem()后的长度!你试试写成<br>My_call(LSend^,LReturn^);
 
对,问题在于我没法控制的我就不会放心<br>毕竟这个函数被调用次数高达每天几万次<br>如果不是我自己释放万一它没释放那不是死翘了?????<br><br>不知道各位平时是怎么写这种调用的?<br><br>
 
用pchar方法是正确的思路,String更易出错,<br>释放亦应该。<br>请onedot试试下列办法:<br>type<br>&nbsp; &nbsp;mypointer=procedure(form:Tform);Far;external;<br>var<br>&nbsp; H:Thandle;<br>&nbsp; p:mypointer;<br>begin<br>&nbsp; H:=loadlibrary('xxx.dll');<br>&nbsp; p:=getprocaddress(H,'p');<br>&nbsp; p(application.yourform);<br>&nbsp; Freelibrary(H);<br>end;<br>
 
不太懂,小天可否解释一下??<br>谢谢
 
type<br>&nbsp; &nbsp;mypointer=procedure(form:Tform);Far;external; //获取该函数的指针<br>var<br>&nbsp; H:Thandle;<br>&nbsp; p:mypointer;<br>begin<br>&nbsp; H:=loadlibrary('xxx.dll'); //调入DLL<br>&nbsp; p:=getprocaddress(H,'p'); //得到此函数名的地址,'p'为函数名<br>&nbsp; p(application.yourform); &nbsp;//运行该函数<br>&nbsp; Freelibrary(H); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //释放DLL<br>end;<br>
 
小天,你的意思是让我自己释放整个DLL资源?<br>我觉得这样有些浪费<br>但要是我真的不清楚它内部处理还是只有这样<br>BTW:还有,你的写法里我不清楚如何具体针对我问题做修改,可否劳驾加一下?<br><br>
 
最好还是用String类型,生存期自管理,不用花心思去理它<br>DLL传参用PChar,并不是所有地方都要用PChar的<br>你用下面的代码应该不会有问题的:<br>var<br>&nbsp; Lsend,LReturn,LResult:string;<br>&nbsp; P: PChar;<br>begin<br>&nbsp; Lsend := 'Test'; //赋值的时候就分配空间了,所以不用再理<br>&nbsp; SetLength(LReturn, 512); //这里要给LReturn分配空间<br>&nbsp; P := PChar(LReturn);//加个P是因为你传入的是VAR类型参数<br>&nbsp; LResult:=My_call(PChar(LSend),P);//LResult你不用理会,Delphi自动会为你分配内存<br>&nbsp; ShowMessage(LResult + ' === ' + Trim(LReturn));<br>end;<br>
 
多人接受答案了。
 
后退
顶部