与C ++ dll的Delphi通讯(参数)

缺口

嗨,我在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构建的。

鲁迪·维特胡斯(Rudy Velthuis)

Startup的声明非常可疑:

__declspec(dllexport) HRESULT Startup(char* version);

转换为:

function Startup(version: PAnsiChar): HResult; stdcall; external 'myDLL.dll';

所以那里应该没有var

我从您的评论中得知,cdecl调用约定适用于您的某些代码。在这种情况下,请删除 stdcall它,因为它否决了前面的内容cdecl

的声明Open()似乎还不错(我将使用DWORDtype,而不是type,Longint尤其是因为现在DWORDLongword这样-但在Win32中它们的大小相同,因此对您没有太大影响)。而且您似乎也在传递正确的参数。

您没有写回什么HRESULT值。但是我认为COM5使用这些设置根本无法打开端口

你能做什么?

您应该var从中删除Startup()

因此,您可以尝试:

  • 在使用cdecl的,而不是stdcall(在stdcall你的声明中否决了cdecl
  • 打开具有不同参数的不同COM端口
  • 解码HRESULT返回的。

很抱歉,如果没有相同的硬件和软件,就不可能从远处更好地诊断。

您可以阅读我有关转换的文章这也有几段说明如何调试代码以找出正确的调用约定。它也可能会帮助您解决转换标头的更多问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章