如何使用动态连接库中参数?(超急) ( 积分: 100 )

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

kaga

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个C写的动态连接库:test.dll<br>其中:<br>SendMsg(<br> &nbsp;const int nNeedReply,<br> &nbsp;const char *sDestTermID,<br> const char *sMsgContent,<br>char *sMsgID,<br>int *nErrorCode <br>);<br>//-------------------------------------------------------<br>说明:<br>输出参数:<br>sMsgID : if success ,message id is filled in nMsgID;<br>nErrorCode : if Fail,error code is filled in nErrorCode<br>返回值:<br>0--OK<br>1--FAIL<br>-------------------------------------------------<br>本人用delphi 调用该函数,在一个独立的单元中有如下声明:<br>//Unit uTest;<br>interface &nbsp;<br> &nbsp;uses<br> &nbsp; &nbsp;....<br> &nbsp;//....<br><br>function SendMsg(<br> &nbsp;nNeedReply :integer;<br> sDestTermID :PChar;<br> sMsgContent : PChar;<br>sMsgID : PChar;<br>nErrorCode : Int):Integer;stdcall;external 'test.dll';<br>//------------------------------------------------------------<br>在实现程序单元<br>unit main;<br>uses <br> &nbsp;uTest,....<br>....<br>//<br>procedure TForm1.Button1Click(Sender:TObject);<br>var<br> &nbsp;nNeedReply : Integer;<br> &nbsp;sDestTermID : PChar;<br> &nbsp;sMsgContent : PChar;<br> &nbsp;sMsgID : PChar;<br> &nbsp;nErrorCode : Integer;<br> &nbsp;CodeList : TStrings;<br>begin<br> &nbsp;CodeList := TStringList.Create;<br> &nbsp;nNeedReply :=1;<br> sMsgContent := PChar('消息测试');<br> nErrorCode :=0;<br> For i:=0 to CodeList.Count-1 do<br> begin<br> &nbsp; sDestTermID := CodeList.Strings;<br> &nbsp; if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br> &nbsp; &nbsp; memLog.lines.add('发送成功')<br> &nbsp;else<br> &nbsp; memLog.lines.add('发送失败');<br> &nbsp;sleep(30);<br>end;<br>end;<br>---------------------------------------<br>结果是这样的:<br>当我发送第一个号码时,能成功;再第二次循环时出现问题。<br>问题提示为:<br> 'Access violation at Ox00404197 : read of address Ox08631057 '<br><br>好象是由sMsgID 引起的,或者也有可能是nErrorCode引起的。<br>因为这2个是DLL的输出值。<br>由于本人功底比较浅薄,希望能得到各位朋友的帮助,帮我看看问题应该出现在什么地方,应如何解决比较好?<br>先谢谢了!
 
有一个C写的动态连接库:test.dll<br>其中:<br>SendMsg(<br> &nbsp;const int nNeedReply,<br> &nbsp;const char *sDestTermID,<br> const char *sMsgContent,<br>char *sMsgID,<br>int *nErrorCode <br>);<br>//-------------------------------------------------------<br>说明:<br>输出参数:<br>sMsgID : if success ,message id is filled in nMsgID;<br>nErrorCode : if Fail,error code is filled in nErrorCode<br>返回值:<br>0--OK<br>1--FAIL<br>-------------------------------------------------<br>本人用delphi 调用该函数,在一个独立的单元中有如下声明:<br>//Unit uTest;<br>interface &nbsp;<br> &nbsp;uses<br> &nbsp; &nbsp;....<br> &nbsp;//....<br><br>function SendMsg(<br> &nbsp;nNeedReply :integer;<br> sDestTermID :PChar;<br> sMsgContent : PChar;<br>sMsgID : PChar;<br>nErrorCode : Int):Integer;stdcall;external 'test.dll';<br>//------------------------------------------------------------<br>在实现程序单元<br>unit main;<br>uses <br> &nbsp;uTest,....<br>....<br>//<br>procedure TForm1.Button1Click(Sender:TObject);<br>var<br> &nbsp;nNeedReply : Integer;<br> &nbsp;sDestTermID : PChar;<br> &nbsp;sMsgContent : PChar;<br> &nbsp;sMsgID : PChar;<br> &nbsp;nErrorCode : Integer;<br> &nbsp;CodeList : TStrings;<br>begin<br> &nbsp;CodeList := TStringList.Create;<br> &nbsp;nNeedReply :=1;<br> sMsgContent := PChar('消息测试');<br> nErrorCode :=0;<br> For i:=0 to CodeList.Count-1 do<br> begin<br> &nbsp; sDestTermID := CodeList.Strings;<br> &nbsp; if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br> &nbsp; &nbsp; memLog.lines.add('发送成功')<br> &nbsp;else<br> &nbsp; memLog.lines.add('发送失败');<br> &nbsp;sleep(30);<br>end;<br>end;<br>---------------------------------------<br>结果是这样的:<br>当我发送第一个号码时,能成功;再第二次循环时出现问题。<br>问题提示为:<br> 'Access violation at Ox00404197 : read of address Ox08631057 '<br><br>好象是由sMsgID 引起的,或者也有可能是nErrorCode引起的。<br>因为这2个是DLL的输出值。<br>由于本人功底比较浅薄,希望能得到各位朋友的帮助,帮我看看问题应该出现在什么地方,应如何解决比较好?<br>先谢谢了!
 
另外:少了一句:<br>CodeList.LoadFromFile('TelCode');<br>//即CodeList中存放了电话号码<br>如下格式:<br>057786777888<br>057786555666<br>057786222333<br>.....
 
既然第一次调用成功说明你的程序没错,会不会dll函数有问题呢
 
试试看这样吧,可能是传递字符串产生的错误<br>procedure TForm1.Button1Click(Sender:TObject);<br>var<br> &nbsp;nNeedReply : Integer;<br> &nbsp;sDestTermID : PChar;<br> &nbsp;sMsgContent : PChar;<br> &nbsp;sMsgID : PChar;<br> &nbsp;nErrorCode : Integer;<br> &nbsp;CodeList : TStrings;<br> &nbsp;procedure Bla(S);<br> &nbsp;var<br> &nbsp;begin<br> &nbsp; &nbsp;if Assigned(sDestTermID) then FreeMem(sDestTermID);<br> &nbsp; &nbsp;sDestTermID := AllocMem(Length(S)+1);<br> &nbsp; &nbsp;Move(S[1], sDestTermID[0], (Length(S));<br> &nbsp;end;<br>begin<br> &nbsp;CodeList := TStringList.Create;<br> &nbsp;nNeedReply :=1;<br> &nbsp;sMsgContent := PChar('消息测试');<br> &nbsp;sDestTermID := nil;<br> &nbsp;nErrorCode :=0;<br> &nbsp;For i:=0 to CodeList.Count-1 do<br> &nbsp;begin<br> &nbsp; &nbsp;//sDestTermID := CodeList.Strings;<br> &nbsp; &nbsp;Bla(CodeList.Strings);<br> &nbsp; &nbsp;if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br> &nbsp; &nbsp; &nbsp;memLog.lines.add('发送成功')<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;memLog.lines.add('发送失败');<br> &nbsp; &nbsp;sleep(30);<br> &nbsp;end;<br> &nbsp;if Assigned(sDestTermID) then FreeMem(sDestTermID);<br>end;
 
to kklili兄:<br>用C写的那个API函数肯定是没有问题的,因为是中兴公司写的,而且很多公司都已经证明是能够用的,关键是,我不知道这样转换成DELPHI,是否有问题。而且第一次是发送成功的,我想应该是没有什么问题的吧。所以我就怀疑在调用函数之后,不仅有个返回值,而且还有输出参数,因为C里面是指针,而DELPHI里,我则没有去动它,不知道是否会出现地址混乱呢?
 
你的声明似乎有点问题,这样是不是好点:<br>function SendMsg(<br> &nbsp;const nNeedReply: Integer;<br> &nbsp;const sDestTermID, sMsgContent: PChar;<br> &nbsp;var sMsgID: PChar;<br> &nbsp;var nErrorCode: PInteger //改了<br>): Integer; stdcall; external 'test.dll';<br>调用时这样:<br>var<br> &nbsp;nNeedReply: Integer;<br> &nbsp;sDestTermID,<br> &nbsp;sMsgContent,<br> &nbsp;sMsgID: PChar;<br> &nbsp;nErrorCode: PInteger; //改了<br>begin<br> &nbsp;nNeedReply := 1;<br> &nbsp;sDestTermID := 'a';<br> &nbsp;sMsgContent := '消息测试';<br> &nbsp;//我不知道你的程序怎么通过编译的,少了个参数<br> &nbsp;SendMsg(nNeedReply, sDestTermID, sMsgContent, sMsgID, nErrorCode);
 
多谢vvyang兄,是我不小心少写了个参数sMsgID.我会再测试一下的。
 
function SendMsg(<br> &nbsp;nNeedReply :integer;<br> sDestTermID :PChar;<br> sMsgContent : PChar;<br>sMsgID : PChar;<br>out nErrorCode : Int):Integer;stdcall;external 'test.dll';<br>翻译时需要根据实际意义翻译才好,因为C++中没有var这样的修饰。<br>var/out的效果和PInteger一样,不过如果根据实际意义翻译成var/out/const会比直接翻译成指针好的多。
 
向zjan521学了一招,谢谢<br><br>nErrorCode这个是不是应该先分配内存<br>[blue]GetMem(nErrorCode, sizeof(Integer));[/blue]<br>For i:=0 to CodeList.Count-1 do<br> &nbsp;begin<br> &nbsp; &nbsp;//sDestTermID := CodeList.Strings;<br> &nbsp; &nbsp;Bla(CodeList.Strings);<br> &nbsp; &nbsp;if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br> &nbsp; &nbsp; &nbsp;memLog.lines.add('发送成功')<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;memLog.lines.add('发送失败');<br> &nbsp; &nbsp;sleep(30);<br> &nbsp;end;<br><br>//用完以后<br>[blue]FreeMem(nErrorCode, sizeof(Integer));[/blue]
 
to chenybin:<br>FreeMem(nErrorCode,sizeof(Integer));<br>用了该语句,在单步执行时,就发生了错误。<br>我其实是直接用了Integer类型的,反倒是没有任何问题。<br>----------------------------------------------------<br>(1) 检查函数是否正确:<br>function SendMsg(<br> &nbsp;nNeedReply :integer;<br> sDestTermID :PChar;<br> sMsgContent : PChar;<br>sMsgID : PChar;<br>nErrorCode : Int):Integer;stdcall;external 'test.dll';<br>这样写是否有需要额外注意的地方??<br>-----------------------------------------<br>(2)本人后来就重新写了一次:<br>....<br>try<br> &nbsp; sDestTermID := CodeList.Strings;<br> &nbsp; if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br> &nbsp; &nbsp; &nbsp;memLog.Lines.Add('Send OK')<br> &nbsp; else<br> &nbsp; &nbsp; &nbsp;memLog.Lines.Add('Send Fail ');<br>except on E :Exception do<br> &nbsp; memLog.Lines.Add(e.message);<br>end;<br>------------------------------------------<br><br>执行结果是:<br>一般情况下是没问题的,但是也会偶尔出现一个意外错误。<br>比如循环发送600条后,一般都会有1-2个异常出现。<br>这说明还是有错误发生,只是本人没有能力对其进行处理(不知道是什么原因造成的)
 
写错了:<br> if SendMsg(nNeedReply,sDestTermID,sMsgContent,nErrorCode) &nbsp;= 0 then<br>应改为:<br> if SendMsg(nNeedReply,sDestTermID,sMsgContent,sMsgID,nErrorCode) &nbsp;= 0 then
 
晕菜。<br>function SendMsg(<br> &nbsp;nNeedReply :integer;<br> sDestTermID :PChar;<br> sMsgContent : PChar;<br>sMsgID : PChar;<br>out nErrorCode : Int):Integer;stdcall;external 'test.dll';<br>var<br> &nbsp;nErrCode : INteger;<br>begin<br> &nbsp;SendMsg(xxx,xxx, ..., nErrCode);
 
是不是应定义成PInteger阿,定义PInteger还出错?没理由阿,听课
 
function SendMsg(<br> &nbsp;nNeedReply :integer;<br> &nbsp;sDestTermID :PChar;<br> &nbsp;sMsgContent : PChar;<br> &nbsp;sMsgID : PChar;<br> &nbsp;var nErrorCode :Integer):Integer;stdcall;external 'test.dll';<br>调用:<br>var<br> &nbsp;sMsgID : PChar;<br> &nbsp;nErrorCode : Integer;<br><br>getmem(sMsgID,255);<br>if SendMsg(nNeedReply,sDestTermID,sMsgContent,sMsgID,nErrorCode) =0 then<br> &nbsp;memLog.Lines.Add('Send OK')<br>else<br> &nbsp; memLog.Lines.Add('Send Fail ');<br>freemem(sMsgID,255);
 
感谢各位兄弟对我的支持,希望下次我们能够更加愉快地交流,再次感谢!
 
后退
顶部