【问题标题】:c++ WINAPI call exported function via GetProcAddressc++ WINAPI通过GetProcAddress调用导出函数
【发布时间】:2016-09-05 12:43:16
【问题描述】:

我试图通过GetProcAddress 获取函数指针来从 DLL 中调用导出函数,但在调用该函数时应用程序崩溃。

我使用dependencywalker 来查看导出的函数是否具有正确的名称。从GetProcAddress 返回的地址不为空。我几乎可以肯定它与调用约定有关,我同时使用了 __cdecl__stdcall 但没有成功。但是我确实想使用GetProcAdress 而不是__declspec(dllimport)

DLL #1(调用者)

  • 将 DLL#2.lib 链接到此 DLL

    typedef void(__stdcall *ptr_init)(DWORD size);
    
    ctx.hModule = LoadLibraryA("someDLL.dll");
    ptr_init init = (ptr_init)GetProcAddress(ctx.hModule, "init");
    
    if (init == NULL) {
        out = out + " | init function is null";
    } else {
        out = out + " | init function found!";//It is found
    }
    
    DWORD test = 10;
    (*init)(test);//<-- makes application crash
    

DLL #2(包含导出函数的DLL)

//header.h
extern "C" __declspec(dllexport) void init(DWORD size);

//source.cpp
extern "C" __declspec(dllexport) void init(DWORD size) {
    //code
}

【问题讨论】:

  • 当你出错时,你没有编译器来帮助你。看起来你弄错了,看起来不是很__stdcall。否则没有令人信服的理由来避免使用调试器。
  • 函数是cdecl。你为什么使用stdcall。你不能写init(测试)。问题可能出在您的 DLL 中。考虑创建一个 MCVE。
  • “但我确实想使用GetProcAdress 而不是__declspec(dllimport)。” - 为什么会这样?如果您只需要控制何时以及如何解析导入,您可以使用delay-loading,并在您的代码中处理导入解析(请参阅Understanding the Helper Function)。

标签: c++ winapi dll dllexport getprocaddress


【解决方案1】:

你应该保持一致。如果您将指针检索为指向 stdcall 函数的指针 - 它必须在实现中声明为 stdcall

//header.h
extern "C" __declspec(dllexport) void __stdcall init(DWORD size);

【讨论】:

  • __stdcall 使应用程序崩溃,但删除所有 __stdcall 有效,这是为什么呢?
  • 因为函数在DLL代码中声明为__cdecl
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
相关资源
最近更新 更多