gpt4 book ai didi

c++ - 在 Delphi 中从 c++ DLL 调用函数

转载 作者:IT老高 更新时间:2023-10-28 23:14:47 33 4
gpt4 key购买 nike

我在 VS2010 中创建了一个新的 c++ DLL 项目,它公开了 1 个函数

#include "stdafx.h"    
#define DllImport extern "C" __declspec( dllimport )
#define DllExport extern "C" __declspec( dllexport )
DllExport int DoMath( int a, int b) {
return a + b ;
}

然后我用 VS2010 创建了一个 C++ 应用程序来测试这个 DLL。在VS2010中构建的测试应用程序可以调用c++ DLL并获得预期的结果。

#include "stdafx.h"
#include <windows.h>

typedef int (*DoMath)(int, int) ;
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hMod = LoadLibrary ("exampleDLL.dll");
if (NULL != hMod) {
DoMath mf1 = (DoMath) GetProcAddress(hMod,"DoMath");
if( mf1 != NULL ) {
printf ("DoMath(8,7)==%d \n", mf1(8,7) );
} else {
printf ("GetProcAddress Failed \n");
}
FreeLibrary(hMod);
} else {
printf ("LoadLibrary failed\n");
return 1;
}
return 0;
}

接下来我尝试在 Delphi 7 中构建一个新项目来调用这个 C++ DLL。我用了this tutorial帮助我建立新项目。

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TmyFunction = function(X,Y: Integer):Integer;

TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
hDll: THandle;
end;

var
Form1: TForm1;
fDoMath : TmyFunction;

implementation
{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
hDll := LoadLibrary('exampleDLL.dll');
if HDll >= 32 then { success }
begin
fDoMath := GetProcAddress(hDll, 'DoMath');
end
else
MessageDlg('Error: could not find exampleDLL.DLL', mtError, [mbOk], 0)
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
i := fDoMath(2,3);
edit1.Text := IntToStr(i);
end;
end.

Delphi 7 项目的结果是 6155731,而我期望 5。我检查了结果的二进制文件,认为它可能与数据类型有关,但在我看来它是随机的。当我重新编译/重新运行应用程序时,每次都会得到相同的结果。

我对 Delphi 了解不多,这是我第一次处理它,我觉得它很困惑。

关于下一步检查什么有什么建议吗?

最佳答案

您需要指定调用约定,在本例中为 cdecl:

TMyFunction = function(X, Y: Integer): Integer; cdecl;

您的代码使用默认的 Delphi 调用约定,即 register 并通过寄存器传递参数。 cdecl 调用约定在堆栈上传递参数,因此这种不匹配解释了为什么两个模块之间的通信失败。


更多评论:

LoadLibrary的失败模式是返回NULL,即0。检查返回值而不是 >=32

使用隐式链接来导入这个函数更简单。用这个简单的声明替换所有 LoadLibraryGetProcAddress 代码:

function DoMath(X, Y: Integer): Integer; cdecl; external 'exampleDLL.dll';

系统加载器将在您的可执行文件启动时解析此导入,因此您不必担心链接的细节。

关于c++ - 在 Delphi 中从 c++ DLL 调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10405991/

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