1

我在 c++ builder 中有一个简单的 DLL。

//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#pragma hdrstop
#pragma argsused


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{

    return TRUE;
}
//---------------------------------------------------------------------------

 extern "C" __declspec(dllexport)  void show_m(void)
{
 MessageBox(NULL, "MSG", "COTI DLL", MB_OK |MB_ICONINFORMATION);
}

当我在 delphi 中调用它时,我得到错误,即 dll 中没有过程:

procedure TForm1.Button1Click(Sender: TObject);
var
  DLL : THandle;
  show_m1 : procedure; cdecl;

begin
    DLL := LoadLibrary('mylib.dll');
    @show_m1:= GetProcAddress(DLL, 'show_m');
    show_m1;
    FreeLibrary(DLL);
end;

有什么问题,它应该可以正常工作,但事实并非如此?

4

1 回答 1

7

您已经找到了解决方案:添加__stdcall调用约定。它起作用的原因是因为原始代码没有指定调用约定,所以__cdecl被使用了。使用extern "C"时,__cdecl调用约定将函数名称导出为"_show_m"(除非您使用 .def 文件来更改它),这就是GetProcAddress()找不到它的原因。改为使用时__stdcall,导出的函数名称"show_m"符合预期。不要忘记更改您的 Delphi 代码以使用stdcall而不是cdecl您的show_m1变量:

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#pragma hdrstop
#pragma argsused


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{

    return TRUE;
}
//---------------------------------------------------------------------------

extern "C" __declspec(dllexport) void __stdcall show_m(void)
{
    MessageBox(NULL, "MSG", "COTI DLL", MB_OK | MB_ICONINFORMATION);
}

.

procedure TForm1.Button1Click(Sender: TObject);
var
  DLL : THandle;
  show_m1 : procedure; stdcall;
begin
  DLL := LoadLibrary('mylib.dll');
  if DLL <> 0 then
  try
    @show_m1 := GetProcAddress(DLL, 'show_m');
    if Assigned(show_m1) then
      show_m1;
  finally
    FreeLibrary(DLL);
  end;
end;
于 2013-02-13T00:56:53.380 回答