从控制台应用程序中动态地使用DLL文件

问题描述 投票:2回答:1

我想创建一个库 Lib.dll 从控制台应用程序中获得动态调用,但找不到该函数。funci() 我想叫。

这个... Lib.dll 是在Visual Studio 2019中创建的一个项目(Console Application,但设置为配置类型:.dll)的结果。

Lib.cpp 是该项目中唯一的文件,只包含代码。

__declspec(dllexport) int funci() 
{
    return 50;
}

我认为我导出的函数是正确的,因为我发现函数是通过使用 DLL导出浏览器v1.66.

enter image description here

然而,我很难通过我的Console应用程序(.exe)找到该函数。

#include <windows.h>
#include <iostream>

typedef int(__cdecl* o_funci)(void);

o_funci funci;

int main()
{
    HINSTANCE hGetProcIDDLL = LoadLibraryA("C:\\Lib.dll");

    if (!hGetProcIDDLL) {
        std::cout << "could not load the dynamic library" << std::endl;
        return EXIT_FAILURE;
    }

    // resolve function address here
    funci = (o_funci) GetProcAddress(hGetProcIDDLL, "funci");
    if (!funci) {
        std::cout << "could not locate the function" << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << "funci() returned " << funci() << std::endl;

    FreeLibrary(hGetProcIDDLL);
}

有些地方出了问题 GetProcAddress 但不知道为什么。我到底是哪里出了问题?

输出。

enter image description here

我一直在看这篇旧帖。从DLL中动态加载一个函数。


EDIT: 解决了,感谢 tenfour

我用的是DependencyWalker。

没有 extern "C" 我可以看到未装饰的 funci 名为 ?funci@@YGHXZ,

enter image description here

所以 funci = (o_funci)GetProcAddress(hGetProcIDDLL, "?funci@@YGHXZ"); 工作。

随着 extern "C" 土豪 funci 名为 _funci@0 - 稍微干净一点。

enter image description here

另一个注意点;使用序数 0x0001 在这两种情况下都起了作用。像这样。funci = (o_funci)GetProcAddress(hGetProcIDDLL, (PCSTR)0x0001);

enter image description here

c++ windows winapi dllexport
1个回答
5
投票

你所使用的工具向你展示的是一个漂亮的导出名版本。它的真实名称将包括名称混杂,这是一个复杂的尝试,将调用信息嵌入到导出名称中。

你有很多选项来使这个工作与 GetProcAddress:

  1. 使用真实的导出名称。您的工具可能有一个选项,可以查看未美化的名称(被篡改的出口名称)。
  2. 使用模块定义文件(*.def)导出函数,你甚至可以指定导出函数的名称为
  3. 以序数代替名称导入
  4. 将函数包装在 extern "C" { ... } 将使用C-style命名,这样可以避免名称混乱。

最常见的解决方案可能是#4,#2紧随其后。

© www.soinside.com 2019 - 2024. All rights reserved.