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

时间:2013-02-12 23:38:53

标签: 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);
}

当我在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;

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

1 个答案:

答案 0 :(得分: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;