嗨,我在Delphi 2007应用程序中集成DLL时遇到了很多问题。
我怀疑呼叫参数做错了什么。目前,我有2个问题,但我认为它们彼此相关。
1)首先使用DLL:从.h文件进行调用:
extern "C" {
__declspec(dllexport) HRESULT Startup(char* version);
}
此调用应初始化DLL,并为我提供DLL的版本。HRESULT应该为0,并且版本指针应包含版本。
我的Delphi代码:
function Startup(var version: Pchar): HRESULT; cdecl; stdcall; external 'myDLL.dll';
和实际的调用:
var
res : HRESULT;
Name1 : PChar;
test : AnsiString;
buf2: array [0..20] of AnsiChar;
begin
FillChar(buf2,20,0);
Name1:= @buf2[0];
res := RdmStartup(Name1);
//Here res = 0, but the Name1 stays empty, and the buf2 still contains 0.
end;
但是由于结果为0,因此调用成功。
然后是我的第二个问题:我需要在DLL中调用一个将打开COM端口的函数。
.h:
extern "C" {
__declspec(dllexport) HRESULT Open(HWND hWnd, int Port, DWORD BaudRate, DWORD Interval);
}
我的Delphi声明:
function Open(hWnd: HWND;Port : integer;BaudRate:LongInt;Interval:LongInt): HRESULT; cdecl; stdcall; external 'myDLL.dll';
我这样称呼:
res:= Open(self.Handle,5,115200,500);
在这里,我从res变量中的DLL返回失败。我也有DLL的来源,而我得到的失败来自DLL正在检查参数是否有效的部分,如果有效,它将继续,否则返回我当前得到的错误。
它正在检查的东西:
if(hWnd == NULL)
{
return false;
}
if(BaudRate != 2400 && BaudRate != 9600 && BaudRate != 38400 && BaudRate != 115200)
{
return false;
}
if(IntervalTimer < 300)
{
return false;
}
std::string strPortName = lexical_cast<std::string>( format("COM%d") % Port);
std::string strPortName(lpPortName.c_str());
std::string::size_type loci = strPortName.find("COM");
if( loci == std::string::npos )
{
return false;
}
return true;
上面的这些之一在我的调用中返回false,因为如果此函数的结果为false,则DLL会给出我当前在结果中得到的错误。有人知道我在做什么错吗?
最后,我尝试了多种类型的组合,我坚持在以下网址找到的转换:http : //www.drbob42.com/delphi/headconv.htm我还尝试了不同的读取char指针的方式,但是所有人都失败了.....
所以在这个阶段,我知道我正在成功地与DLL通信,因为我为2个调用返回了不同的HRESULT,但是我怀疑我的参数不能正常工作。
我使用的是Delphi 2007,C ++ DLL是使用VS2010构建的。
Startup的声明非常可疑:
__declspec(dllexport) HRESULT Startup(char* version);
转换为:
function Startup(version: PAnsiChar): HResult; stdcall; external 'myDLL.dll';
所以那里应该没有var
。
我从您的评论中得知,cdecl
调用约定适用于您的某些代码。在这种情况下,请删除 stdcall
它,因为它否决了前面的内容cdecl
。
的声明Open()
似乎还不错(我将使用DWORD
type,而不是type,Longint
尤其是因为现在DWORD
是Longword
这样-但在Win32中它们的大小相同,因此对您没有太大影响)。而且您似乎也在传递正确的参数。
您没有写回什么HRESULT
值。但是我认为COM5
使用这些设置根本无法打开端口。
您应该var
从中删除Startup()
。
因此,您可以尝试:
cdecl
的,而不是stdcall
(在stdcall
你的声明中否决了cdecl
)HRESULT
返回的。很抱歉,如果没有相同的硬件和软件,就不可能从远处更好地诊断。
您可以阅读我有关转换的文章。这也有几段说明如何调试代码以找出正确的调用约定。它也可能会帮助您解决转换标头的更多问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句