gpt4 book ai didi

c++ - Delphi与C++dll通信(参数)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:58 25 4
gpt4 key购买 nike

您好,我在将 DLL 集成到我的 Delphi 2007 应用程序时遇到了很多问题。

我怀疑我对调用的参数做错了什么。目前我有 2 个问题,但我认为它们彼此相关。

1)首先调用 DLL:来自 .h 文件:

extern "C" {

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

}

此调用应初始化 DLL 并返回 DLL 的版本。 HRESULT 应为 0,版本指针应包含版本。

我的德尔福代码:

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我也尝试过不同的读取字符指针的方法,但都失败了......

所以在这个阶段我知道我正在与 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 作为类型,而不是 Longint,特别是因为 DWORD 现在是 Longword -- 但在 Win32 中它们的大小相同,所以这对您来说不会有什么大的不同)。而且您似乎也传递了正确的参数。

你没有写你得到的 HRESULT 值是什么。但我假设端口 COM5 根本无法使用这些设置打开。

你能做什么?

您应该从 Startup() 中删除 var

所以你可以试试:

  • 使用 cdecl 而不是 stdcall(声明中的 stdcall 否决 cdecl)
  • 用不同的参数打开不同的COM端口
  • 解码返回的 HRESULT

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

你可以阅读我的 article on conversion .这还有几段解释了如何调试代码以找出正确的调用约定。它也可以帮助您解决更多转换 header 的问题。

关于c++ - Delphi与C++dll通信(参数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39471902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com