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