我在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)
有什么不对,它应该是正确的,但事实并非如此?
您已经发现了解决方案:添加__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)