Delphi调用C的DLL库出错(100分)

  • 主题发起人 主题发起人 taizi
  • 开始时间 开始时间
T

taizi

Unregistered / Unconfirmed
GUEST, unregistred user!
一. c写的DLL中的关键代码
#pragma pack(1)
typedef struct _tagInfo
{
char *pszServerIP;
int iServerPort;
int iTransType;
}DLLINFO;
#pragma pack()

extern "C&quot
int __declspec(dllexport) __stdcall SetTag(DLLINFO *dllinfo,
char *pszServerIP,int iServerPort,int iTransType);
extern "C&quot
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:wencui_zh@hotmail.com
qq :56741246. 谢谢。
 
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;
 
楼上的可不可以帮我解释一下 为什么 ptagInfo: pDllInfo
这个参数不要定义成 var形式的。ptagInfo所指结构中的内容已经在设置的时候被改变了,而且我也希望这个改变过的值在下一个接口函数中可以用到,以前我在delphi中想通过输出参数将结果带回来的都是把参数定义成 var 形式的,现在这个指针类型的参数为什么不用定义成 var 了呢?
 
因为你本身是指针类型
指针所指向地址的内容改变就已经等于你的结构内容改变
指针不变
 
后退
顶部