一. c写的DLL中的关键代码
#pragma pack(1)
typedef struct _tagInfo
{
    char    *pszServerIP;
    int    iServerPort;
    int    iTransType;   
}DLLINFO;
#pragma pack()extern "C" int __declspec(dllexport) __stdcall SetTag(DLLINFO *dllinfo,
char *pszServerIP,int iServerPort,int iTransType);
extern "C" int __declspec(dllexport) __stdcall GetTag(DLLINFO *dllinfo,
char  **pszRetServerIP,int *piRetServerPort,int *piRetTransType);int __stdcall SetTag(DLLINFO *dllinfo,char *pszServerIP,int lServerPort,int lTransType)
{
 dllinfo->pszServerIP=(char*)calloc(strlen(pszServerIP)+1,sizeof(char));
 strcpy(dllinfo->pszServerIP,pszServerIP);
 dllinfo->iServerPort=lServerPort;
 dllinfo->iTransType=lTransType;
 return 0;
}int __stdcall GetTag(DLLINFO *dllinfo,char **pszRetServerIP,
int *plRetServerPort,int *plRetTransType)
{
          *pszRetServerIP=(char*)calloc(strlen(dllinfo->pszServerIP)+1,sizeof(char));
 strcpy(*pszRetServerIP,dllinfo->pszServerIP);
 *piRetServerPort=dllinfo->iServerPort;
 *piRetTransType=dllinfo->iTransType;
 return 0;
}二. Delphi中调用代码 1.声明部分
unit DllApi;interface
type
  tagDllInfo = packed record
   strServerIP: pchar ;
   iServerPort: integer ;
   iTransType : integer 
  end;  pDllInfo = ^tagDllInfo;  function  SetTag (var ptagInfo: pDllInfo; strServerIP: pchar; iServerPort: integer; iTransType: integer):integer;stdcall;
  function  GetTag (var ptagInfo: pDllInfo; var strRetServerIP: pchar; var iRetServerPort: integer; var iRetTransType: integer):integer;stdcall;implementation
function SetTag;Stdcall;{Cdecl;} external 'Cdll.dll' name 'SetTag';
function GetTag;Stdcall;{Cdecl;} external 'Cdll.dll' name 'GetTag';end.2.调用的主要代码
unit MRTDDemo;begin 
var
 ptagInfo: pDllInfo;   
 taginfo : tagDllInfo; strRetIP : pchar;
 iRetPort : integer;
 iRetType : integer;
 iRet     : integer; 
    iServerPort:integer;
    iTransType:integer;begin
    ptagInfo := @taginfo;
    iRet := SetTag (ptagInfo,pchar('192.168.9.57'),2323,34);
    iRet := GetTag (ptagInfo,strRetIP,iRetPort,iRetType);    iServerPort :=ptagInfo^.iServerPort;
    iTransType :=ptagInfo^.iTransType;
end;
end.
  
如上是我做的一个简单的Delphi调用C的DLL动态库的例子,现在delphi的测试程序可以调用dll,但是 SetTag (ptagInfo,pchar('192.168.9.57'),2323,34);这个函数的几个参数设置进去后,再调用 GetTag (ptagInfo,strRetIP,iRetPort,iRetType);取回已设置的数值,其中观察 strRetIP、iRetType 可以返回正确的值,即'192.168.9.57'、34,可是 iRetPort却返回0,我在C的动态库的代码里跟踪 发现在接口函数SetTag (ptagInfo,pchar('192.168.9.57'),2323,34);调用结束函数退出后,iRetPort 对应的内存地址里边的数值被清0了。主要是这样:在这个结构中struct _tagInfo
{
    char    *pszServerIP;
    int    iServerPort;
    int    iTransType;   
}DLLINFO;  每次在调用SetTag () 将结构体中的各个值设置成功,函数结束退出后,结构体中对应的第二个域(即使结构中域的个数和数据类型变化)的内容总是被改为无效值,即0或者空。接下来调用iServerPort :=ptagInfo^.iServerPort;
                   iTransType :=ptagInfo^.iTransType; 发现这两个值都变成了很大的整数。
但是这个dll用C写的测试程序调用没有问题。我不明白是什么原因导致了如上的错误,请帮我看看我的声明及其调用过程中是否有问题。
谢谢,如果我的问题没有描述清楚或者您发现了我在处理过程中的错误,请跟我联系,我将不胜感激。我的msn:[email protected] 
              qq :56741246.          谢谢。

解决方案 »

  1.   

    声名改下:传入的已经是指针了,所以不用Var.
      function  SetTag (var ptagInfo: pDllInfo; strServerIP: pchar; iServerPort: integer; iTransType: integer):integer;stdcall;
      function  GetTag (var ptagInfo: pDllInfo; var strRetServerIP: pchar; var iRetServerPort: integer; var iRetTransType: integer):integer;stdcall;-------------------------》》》》》》》》》》》》》》》》》》》》》》》》》  function  SetTag (ptagInfo: pDllInfo; strServerIP: pchar; iServerPort: integer; iTransType: integer):integer;stdcall;
      function  GetTag (ptagInfo: pDllInfo; var strRetServerIP: pchar; var iRetServerPort: integer; var iRetTransType: integer):integer;stdcall;