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

What is wrong in calling procedure from c++ DLL

本文关键字:什么 问题 过程 c++DLL 调用      更新时间:2023-10-16

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

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

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

#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;