如何在 Microsoft Visual C++ 中导入 dll

我有一个 DLL,我想使用它的一些功能.

I have a DLL and I would like to use some of its functions.

#include <iostream>

using namespace std;

extern "C" __declspec(dllimport) int Initialize(char* localPort, char* adminServerName, int rpcTimeout);


int main()
{
    int res = Initialize("7864", "6000@kabc", 10000);

    return 0;
}

我没有 DLL 的 .lib 文件,所以无论如何我可以链接到它.我想到的一件事是使用 LoadLibrary 函数,然后使用 GetProcAddress().有没有其他办法?

I don't have the DLL's .lib file, so is there anyway I can link to it. One thing that comes to my mind is to use the LoadLibrary function and then use the GetProcAddress(). Is there any other way?

当我编译以下代码时

  • 错误 LNK2019:未解析的外部符号 _imp_Initialize 在函数 _main 中引用

  • error LNK2019: unresolved external symbol _imp_Initialize referenced in function _main

致命错误 LNK1120:1 个未解决的外部问题

fatal error LNK1120: 1 unresolved externals

我收到上述错误

我使用的是 Windows 和 Visual Studio 2008

I'm using Windows and Visual Studio 2008

推荐答案

从你的措辞很明显你正在使用 Dev Studio 的某个或其他版本.

From your phrasing it is pretty clear you are using Dev Studio some or other version.

为了隐式链接到一个 dll,VC++需要一个 .lib 文件,没有问题.如果没有 .lib,您只能使用 LoadLibrary 和 GetProcAddress 显式加载 dll.

In order to implicitly link against a dll, VC++ needs a .lib file, no questions. Without a .lib you can only explicitly load the dll using LoadLibrary and GetProcAddress.

幸运的是,导入库只包含 dll 的导出符号,因此在 VC++ 中简单地创建一个导出相同符号的 dll 项目,构建它,然后使用生成的 .lib 文件访问目标 dll 是完全合法的.

Fortunately import libraries contain nothing other than the dll's exported symbols, so it is perfectly legitimate to simply create a dll project in VC++ that exports the identical symbols, build it, and then use the resulting .lib file to access the target dll.

真正的诀窍是,正确使用符号:根据原始 dll 的创建方式,可能需要处理一些装饰.

The trick really is, getting the symbols right: Depending on how the original dll was created there might be some decoration to deal with.

当使用 dependencywalker

  • "Initialize" - 通过 .DEF 文件或通过 extern "C" __declspec(dllexport) int __cdecl Initialize(...
  • 导出
  • "_Initalize@16" - 使用以下方式导出:extern "C" __declspec(dllexport) int __stdcall Initialize(...
  • ?Initialize@@YAHPADOH@Z" - `__declspec(dllexport) int Initialize(char*,char*,int);
  • ?Initialize@@YGHPADOH@Z" - `__declspec(dllexport) int __stdcall Initialize(char*,char*,int);

问题确实是第一种情况 - 如果调用约定不是 __cdecl(并且大多数 dll api 实际上是 __stdcall - 所有 Windows dll 都是 __stdcall),那么您必须使用 .def 文件来导出未修饰的名称.

The problem really is the first case - if the calling convention isn't __cdecl (and most dll api's are actually __stdcall - all windows dlls are __stdcall) then you must use a .def file to export the undecorated names.

相关文章