从c ++ DLL调用过程有什么问题

Jac*_*cek 1 c++ delphi dll

我在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);
}
Run Code Online (Sandbox Code Playgroud)

当我在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;
Run Code Online (Sandbox Code Playgroud)

有什么不对,它应该是正确的,但事实并非如此?

Rem*_*eau 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);
}
Run Code Online (Sandbox Code Playgroud)

.

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;
Run Code Online (Sandbox Code Playgroud)