DELPHI调用C++编写的DLL问题(200分)

  • 主题发起人 主题发起人 whaway
  • 开始时间 开始时间
W

whaway

Unregistered / Unconfirmed
GUEST, unregistred user!
//用DELPHI来调用C++编写的DLL(此DLL有VC的调用例程),涉及C++译成相应的DELPHI程序问题,
//怀疑是不是C++的指针和DELPHI的指针有细小的差别,环境为Win2000+sp4,Delphi 6,VC 6,
//问题如下:
//●●DLL中的函数声明*.h头文件(部分):
//================================================
//结构声明
typedef struct _HKCANHANDLE {
HANDLE mHandle;
DWORD mGuid;
WORD mClass;
WORD mDev;
WORD mType;
WORD mState;
}HKCANHANDLE,*PHKCANHANDLE;
typedef struct _HKCANFRAME {
UCHAR nPort;
UCHAR mFrame[10];
}HKCANFRAME,*PHKCANFRAME;
//函数声明
extern BOOL _stdcall HKCanSendFrame(PHKCANHANDLE mDevHandle,
PHKCANFRAME pSendFrame);
extern int _stdcall HKCanReadFrame(PHKCANHANDLE mDevHandle,
int nPort,
PHKCANFRAME pReadFrame);
//●●VC中对这两个函数的调用(运行完全正常):
//================================================
HKCANFRAME m_snd,m_rec;
HKCANHANDLE m_devicehandle;
int Temp;
Send = HKCanSendFrame(&m_devicehandle,&m_snd);
Read = HKCanReadFrame(&m_devicehandle,Temp,&m_rec);
//●●DELPHI转译*.h文件为*.PAS文件(对应):
//================================================
//结构声明
type
_HKCANHANDLE = record
mHandle: THandle;
mGuid: DWord;
mClass: Word;
mDev: Word;
mType: Word;
mState: Word;
end {_HKCANHANDLE};
HKCANHANDLE = _HKCANHANDLE;
PHKCANHANDLE = ^_HKCANHANDLE;
type
_HKCANFRAME = record
nPort: UCHAR;
mFrame: array[0..10- 1] of UCHAR;
end {_HKCANFRAME};
HKCANFRAME = _HKCANFRAME;
PHKCANFRAME = ^_HKCANFRAME;
//函数声明
function HKCanSendFrame(var mDevHandle: HKCANHANDLE;
var pSendFrame: HKCANFRAME): Bool cdecl{$IFDEF WIN32} stdcall{$ENDIF};
function HKCanReadFrame(var mDevHandle: HKCANHANDLE;
nPort: Integer;
pReadFrame: HKCANFRAME): Integer cdecl{$IFDEF WIN32} stdcall{$ENDIF};
//●●DELPHI对函数的调用(问题在这里):
//================================================
m_snd, m_rec: HKCANFRAME;
m_devicehandle: HKCANHANDLE;
TempPort:integer;
Send := HKCanSendFrame(m_devicehandle, m_snd);//此函数运行完全正常,返回值正确
Read := HKCanReadFrame(m_devicehandle, TempPort, m_snd);
//调用就出现'access violation at 0x10001ebd:write of address 0x01080100'错误
//HKCanSendFrame两个参数都是输入
//HKCanReadFrame三个参数是输入,输入,输出
//因此怀疑问题就出在这,不知道怎么解决
 
//改成以下试试
type
_HKCANHANDLE = packed record
mHandle: THandle;
mGuid: DWord;
mClass: Word;
mDev: Word;
mType: Word;
mState: Word;
end {_HKCANHANDLE};
HKCANHANDLE = _HKCANHANDLE;
PHKCANHANDLE = ^_HKCANHANDLE;
type
_HKCANFRAME = packed record
nPort: UCHAR;
mFrame: array[0..10- 1] of UCHAR;
end {_HKCANFRAME};
HKCANFRAME = _HKCANFRAME;
PHKCANFRAME = ^_HKCANFRAME;
//函数声明
function HKCanSendFrame(mDevHandle: PHKCANHANDLE;
pSendFrame: PHKCANFRAME): Bool stdcall;
function HKCanReadFrame(mDevHandle: PHKCANHANDLE;
nPort: Integer;
pReadFrame: PHKCANFRAME): Integer stdcall;
 
packed record我试过了,问题是一样的。
可能是我没说清楚吧,是这样的:
在VC中,
调用两个函数都正常;
在DELPHI中,
调用HKCanSendFrame一切正常,
而调用HKCanReadFrame就出错了。
 
对于VC写的DLL,D7支持的比较好,不过使用cdecl调用,都去掉stdcall,
按照你那样这样定义
function HKCanReadFrame(var mDevHandle: HKCANHANDLE;
nPort: Integer;
var pReadFrame: HKCANFRAME): Integer;cdecl;external 'xx.dll' name 'HKCanReadFrame';
应该是可以的,你试试看了,我用过,不过这样调用不太好,使用动态调用好一点
都是要用cdecl调用才好,你用stdcall调用的话有时对有时错,有时异常的。
 
function HKCanReadFrame(var mDevHandle: HKCANHANDLE;
nPort: Integer;
pReadFrame: HKCANFRAME): Integer cdecl{$IFDEF WIN32} stdcall{$ENDIF};
最后一个参数改成var试试
function HKCanReadFrame(var mDevHandle: HKCANHANDLE;
nPort: Integer;
var pReadFrame: HKCANFRAME): Integer cdecl{$IFDEF WIN32} stdcall{$ENDIF};
 
[blue]
感谢两位的指导,现在问题已经解决了。
//HKCanSendFrame两个参数都是输入
//HKCanReadFrame三个参数是输入,输入,输出
//因此怀疑问题就出在这,不知道怎么解决
tongdanfeng提出加在第三个参数加VAR,
经试验成功了,仔细回想一下,加这个VAR是不无道理的。
谢谢了。[/blue]

 
后退
顶部