从c+;调用过程有什么问题+;动态链接库 我在C++ Builder中有一个简单的DLL。
从c+;调用过程有什么问题+;动态链接库 我在C++ Builder中有一个简单的DLL。,c++,delphi,dll,C++,Delphi,Dll,//--------------------------------------------------------------------------- #include <vcl.h> #include <windows.h> #pragma hdrstop #pragma hdrstop #pragma argsused BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvRe
//---------------------------------------------------------------------------
#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);
}
出了什么问题,它应该工作正常,但它不是?您已经找到了解决方案:添加
\uu stdcall
调用约定。它之所以能工作,是因为原始代码没有指定调用约定,所以使用了\uuu cdecl
。当使用extern“C”
时,调用约定将函数名导出为“\u show\u m”
(除非使用.def文件更改),这就是GetProcAddress()
找不到它的原因。使用\uu 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);
}
#包括
#包括
#布拉格语hdrstop
#布拉格语hdrstop
#布拉格语
BOOL WINAPI DllMain(HINSTANCE hinstDLL、DWORD fwdreason、LPVOID lpvReserved)
{
返回TRUE;
}
//---------------------------------------------------------------------------
外部“C”\uuuuu declspec(dllexport)无效\uuuuu stdcall show\uu m(无效)
{
消息框(空,“消息”,“COTI DLL”,MB|U OK | MB|U图标信息);
}
procedure TForm1.按钮1点击(发送方:TObject);
变量
DLL:THandle;
show_m1:程序;stdcall;
开始
DLL:=LoadLibrary('mylib.DLL');
如果DLL为0,则
尝试
@show_m1:=GetProcAddress(DLL,'show_m');
如果分配(显示m1),则
显示_m1;
最后
免费图书馆(DLL);
结束;
结束;
您已经找到了解决方案:添加\uu stdcall
调用约定。它之所以能工作,是因为原始代码没有指定调用约定,所以使用了\uuu cdecl
。当使用extern“C”
时,调用约定将函数名导出为“\u show\u m”
(除非使用.def文件更改),这就是GetProcAddress()
找不到它的原因。使用\uu 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);
}
#包括
#包括
#布拉格语hdrstop
#布拉格语hdrstop
#布拉格语
BOOL WINAPI DllMain(HINSTANCE hinstDLL、DWORD fwdreason、LPVOID lpvReserved)
{
返回TRUE;
}
//---------------------------------------------------------------------------
外部“C”\uuuuu declspec(dllexport)无效\uuuuu stdcall show\uu m(无效)
{
消息框(空,“消息”,“COTI DLL”,MB|U OK | MB|U图标信息);
}
procedure TForm1.按钮1点击(发送方:TObject);
变量
DLL:THandle;
show_m1:程序;stdcall;
开始
DLL:=LoadLibrary('mylib.DLL');
如果DLL为0,则
尝试
@show_m1:=GetProcAddress(DLL,'show_m');
如果分配(显示m1),则
显示_m1;
最后
免费图书馆(DLL);
结束;
结束;
你能用它来检查mylib.dll的导出吗?我应该从中看到什么,因为我在那里打开的dll 100%工作,而这个dll不工作,并且在这个工具中它们看起来都一样?当你在左边的列表中选择你的库时,你应该看到右边库中定义的导出。如果可能的话,使用您可以使用的任何调试器(我对Delphi完全不熟悉),检查mylib.dll加载到进程中时的路径;也许它发现了一个不正确的mylib.dll?您发布的代码不可能给出一个dll中没有过程的错误,它应该引起的是一个AV。由于不检查LoadLibrary和GetProcAddress的返回,因此如果dll没有未分配的过程,则会调用该过程。不要使用THandle
作为LoadLibrary
的返回值。它不是一个THandle
。它是一个HMODULE
。正如Sertac所说,检查错误将是一个很好的举措。你能用它来检查mylib.dll的导出吗?我应该从中看到什么,因为我在那里打开了dll,它100%工作,而这个dll不工作,在这个工具中,它们看起来都一样?当你在左边的列表中选择你的库时,您应该可以在右侧的库中看到定义的导出。如果可能的话,使用您可以使用的任何调试器(我对Delphi完全不熟悉),检查mylib.dll加载到进程中时的路径;也许它发现了一个不正确的mylib.dll?您发布的代码不可能给出一个dll中没有过程的错误,它应该引起的是一个AV。由于不检查LoadLibrary和GetProcAddress的返回,因此如果dll没有未分配的过程,则会调用该过程。不要使用THandle
作为LoadLibrary
的返回值。它不是一个THandle
。它是一个HMODULE
。正如塞塔克所说,检查错误将是一个很好的举措。
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;