请教一下如何处理DLL函数中的结构指针? ( 积分: 100 )

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

kaga

Unregistered / Unconfirmed
GUEST, unregistred user!
//说明: 动态链接库是用C语言开发的'SMGWAPI.DLL'<br>接收短信 SMGPDeliver()<br>-------------------------------------------------------------------------------<br>参数名 &nbsp; 数据类型 &nbsp; 说明<br>-------------------------------------------------------------------------------<br>nTimeout nt &nbsp; &nbsp; &nbsp; 输入等待的最大延时,如果是0表示永远等待。单位为秒<br>pDeliverResp &nbsp; DeliverResp* &nbsp; 保存短信的DeliverResp结构指针<br>------------------------------------------------------------------------------<br><br>DeliverResp结构<br>---------------------------------------------------------<br>参数名 &nbsp; 数据类型 &nbsp; 说明<br>---------------------------------------------------------<br>sMsgID char(11) 短消息标识<br>nIsReport Int 是否状态报告:=1<br>nMsgFormat Int 信息格式:填写=15<br>sRecvTime char(16) 接收时间yyyymmddhhmiss<br>sSrcTermID char(22) &nbsp; &nbsp; &nbsp; &nbsp;本机号码(1061222)<br>sDestTermID &nbsp; &nbsp; char(22) &nbsp; &nbsp; &nbsp; &nbsp; 对方号码<br>nMsgLen Int 短信长度<br>sMsgContent char(22) 短信内容<br>--------------------------------------------------------<br><br>unit uSMGWAPI;<br>uses <br> &nbsp; ......<br>type<br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;<br>.....<br> function SMGPDeliver(const nTimeout : Integer; pDr : PDeliverResp):Integer;stdcall;external 'SMGWAPI.DLL';<br>....<br><br><br>主程序中调用<br>uses<br> &nbsp;uSMGWAPI;<br>.....<br><br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;<br><br>procedure TfrmServer.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;i : Integer; &nbsp;<br> &nbsp;pDr : PDeliverResp;<br>begin<br> &nbsp; new(pDr);<br> &nbsp; if uSMGWAPI.SMGPDeliver(3,pDr)=0 then &nbsp;//这里提示错误<br> &nbsp; &nbsp; &nbsp; memLog.lines.add(pDr^.sMsgID+pDr^.sMsgContent+pDr^.sSrcTermID); &nbsp;<br> &nbsp; Dispose(pDr);<br><br>end;<br>--------------------------------------------------------------<br>编译提示错误:types of actual and formal var parameters must be indentical.<br>--------------------------------------------------------------<br>另外,我把短信接收的结构(uSMGWAPI,uServer中)均修改为:<br>TDeliverResp= record<br> &nbsp; &nbsp; sMsgID : PChar;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : PChar;<br> &nbsp; &nbsp; sSrcTermID : PChar;<br> &nbsp; &nbsp; sDestTermID : PChar;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : PChar;<br> &nbsp;end;<br> &nbsp;PDeliverResp=^TDeliverResp;<br>也提示错误?<br><br>请问各位大侠,我应该如何处理该结构?
 
//说明: 动态链接库是用C语言开发的'SMGWAPI.DLL'<br>接收短信 SMGPDeliver()<br>-------------------------------------------------------------------------------<br>参数名 &nbsp; 数据类型 &nbsp; 说明<br>-------------------------------------------------------------------------------<br>nTimeout nt &nbsp; &nbsp; &nbsp; 输入等待的最大延时,如果是0表示永远等待。单位为秒<br>pDeliverResp &nbsp; DeliverResp* &nbsp; 保存短信的DeliverResp结构指针<br>------------------------------------------------------------------------------<br><br>DeliverResp结构<br>---------------------------------------------------------<br>参数名 &nbsp; 数据类型 &nbsp; 说明<br>---------------------------------------------------------<br>sMsgID char(11) 短消息标识<br>nIsReport Int 是否状态报告:=1<br>nMsgFormat Int 信息格式:填写=15<br>sRecvTime char(16) 接收时间yyyymmddhhmiss<br>sSrcTermID char(22) &nbsp; &nbsp; &nbsp; &nbsp;本机号码(1061222)<br>sDestTermID &nbsp; &nbsp; char(22) &nbsp; &nbsp; &nbsp; &nbsp; 对方号码<br>nMsgLen Int 短信长度<br>sMsgContent char(22) 短信内容<br>--------------------------------------------------------<br><br>unit uSMGWAPI;<br>uses <br> &nbsp; ......<br>type<br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;<br>.....<br> function SMGPDeliver(const nTimeout : Integer; pDr : PDeliverResp):Integer;stdcall;external 'SMGWAPI.DLL';<br>....<br><br><br>主程序中调用<br>uses<br> &nbsp;uSMGWAPI;<br>.....<br><br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;<br><br>procedure TfrmServer.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;i : Integer; &nbsp;<br> &nbsp;pDr : PDeliverResp;<br>begin<br> &nbsp; new(pDr);<br> &nbsp; if uSMGWAPI.SMGPDeliver(3,pDr)=0 then &nbsp;//这里提示错误<br> &nbsp; &nbsp; &nbsp; memLog.lines.add(pDr^.sMsgID+pDr^.sMsgContent+pDr^.sSrcTermID); &nbsp;<br> &nbsp; Dispose(pDr);<br><br>end;<br>--------------------------------------------------------------<br>编译提示错误:types of actual and formal var parameters must be indentical.<br>--------------------------------------------------------------<br>另外,我把短信接收的结构(uSMGWAPI,uServer中)均修改为:<br>TDeliverResp= record<br> &nbsp; &nbsp; sMsgID : PChar;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : PChar;<br> &nbsp; &nbsp; sSrcTermID : PChar;<br> &nbsp; &nbsp; sDestTermID : PChar;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : PChar;<br> &nbsp;end;<br> &nbsp;PDeliverResp=^TDeliverResp;<br>也提示错误?<br><br>请问各位大侠,我应该如何处理该结构?
 
去掉声明中得const。<br>function SMGPDeliver({const}nTimeout : Integer; pDr : PDeliverResp):Integer;stdcall;external 'SMGWAPI.DLL';
 
本人估计是指针结构方面出了什么问题,但是苦于一直找不出到底是何原因?
 
sMsgContent : Array[0..251] of char;<br> 这个是不是笔误?应是21吧<br><br>function SMGPDeliver(const nTimeout : Integer; pDr : PDeliverResp):Integer;stdcall;external 'SMGWAPI.DLL';<br>这里的const去掉<br><br>提示信息应该是常量和变量的问题
 
不好意思,是我的笔误:<br>sMsgContent char(252) 短信内容<br>所以结构中定义应为:sMsgContent : Array[0..251] of char;
 
修改了以后还有问题吗?不用const限定,其实你可以把VC的导出函数原型写出来
 
你在两个单元中分别都定义了下面的类型,这样在uSMGWAPI定义中,函数引用的类型与主程序单元中引用的两个TDeliverResp(根据引用优先原则),编译器认为类型是不同的。解决办法是把主程序单元的定义去掉。另外,我觉得record可能要加packed,一般C定义的结构为了避免编译器的岐义解释,一般字段是紧凑排列的。<br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;
 
谢谢lichengbin和chengbin兄,我再试试看
 
类型即使是重定义了也没有关系,DELPHI中的RECORD是最基本的数据结构,仅仅代表一段内存,仅此而已,和C++中的STRUCT是不同的。因此主单元的定义可以不删除,只要定义的一样,删不删除程序运行结果都是一样的,不过为了整个程序的逻辑性,对于同一个数据结构,自然不应该出现多个定义.<br>TDeliverResp = packed record<br>这是通常选项(绝大多数时候,你可以使用sizeof验证),.声明与楼上的/楼主最初声明相同.而声明为PChar的那个结构是完全错误,不可理解的
 
类型定义重了是有关系的,因为编译器并不认为两者是同一个数据类型,尽管他们的内存布局是一样的,就象Integer占4个字节,Pointer也占4个字节,但我们不能说这两者内存布局、内存占用相同就在需要传Integer的地方传Pointer参数吧?[:D] zjan521兄,可以实测一下,一般是会出现&quot;incompatible types 'xxx' and 'xxx'的。<br>当然,强制类型转换一下是可以的,如uSMGWAPI.PDeliverResp(pDr)
 
呵呵,我的意思主要是逻辑上.因为RECORD,实际上就是内存,因此他没有CLASS那一套东西.语法自然有差别.另外,如果两个都是全局的,其实声明本身就是错误的,命名冲突.<br>DELPHI的所谓强类型,实在没办法.在DELPHI中强制转换,是很正常的.
 
全局的两个同名结构或类的声明,不会命名冲突出错,因为两个Unit分属不同的NameSpace,Delphi自身就有这样的情况,如Windows.TBitmap和Graphics.TBitmap,主要是引用时要避免交叉混淆。据我个人的使用经验来看,编译器是根据引用优先原则来进行编译的,一看当前Unit有没有需要的结构或类说明,二看包含结构或类说明的Unit中哪个离引用之处最近。
 
kaga,<br>编译通不过是因为语法错误,<br>调用出错才可能是结构定义得问题
 
呵呵,我所说的仅仅是逻辑上的,如果一个程序处处都要靠语法来维持整体逻辑,乱套了.<br>KEKE,呵呵,语多必失。
 
一般这样安全,试试看<br> &nbsp;PDeliverResp = ^TDeliverResp;<br> &nbsp;TDeliverResp = packed record //加多packed record<br> &nbsp; &nbsp; sMsgID : Array[0..10] of char;<br> &nbsp; &nbsp; nIsReport : Integer;<br> &nbsp; &nbsp; nMsgFormat : Integer;<br> &nbsp; &nbsp; sRecvTime : Array[0..15] of char;<br> &nbsp; &nbsp; sSrcTermID : Array[0..21] of char;<br> &nbsp; &nbsp; sDestTermID : Array[0..21] of char;<br> &nbsp; &nbsp; nMsgLen : Integer;<br> &nbsp; &nbsp; sMsgContent : Array[0..251] of char;<br> &nbsp;end;<br>...................<br><br> &nbsp; getmem(pDr,sizeof(TDeliverResp));//用getmem<br> &nbsp; if uSMGWAPI.SMGPDeliver(3,pDr)=0 then &nbsp;<br> &nbsp; &nbsp; &nbsp; memLog.lines.add(pDr^.sMsgID+pDr^.sMsgContent+pDr^.sSrcTermID); &nbsp;<br> &nbsp; freemem(pDr);//用freemem
 
非常感谢zjan521不厌其烦地指导,感谢lichengbin,chengbin,还有41426277,tt.t兄弟的解答,谢谢大家!过段时间,我会重新整理一下,把正确的代码公布出来,希望能对遇到同样问题的朋友们一些启发,再次感谢楼上兄弟的支持!
 
后退
顶部