【问题标题】:How to build with required `.dll` in Windows 10 Visual Studio如何在 Windows 10 Visual Studio 中使用所需的“.dll”进行构建
【发布时间】:2017-05-10 16:22:12
【问题描述】:

我正在尝试构建一个项目。我有需要在我的项目中使用的a.lib 文件。我知道有两种方法可以使用这个库:

  • 使用#pragma comment(lib, "a.lib")添加它
  • 将其添加到链接器依赖项Configuration Properties -> Linker -> Input -> Additional Dependencies

现在,a.lib 使用 StackWalk64 函数 DbgHelp。该库以DbgHelp.libDbgHelp.dll 的形式提供。我知道我可以使用上面列出的两种方式将其用作lib。但是如果我不想将它包含到我的项目中并想使用DbgHelp.dll,我该如何在 Visual Studio 中做到这一点?

【问题讨论】:

标签: c++ visual-studio-2015


【解决方案1】:

如果您想调用 DLL 中的函数,但不想链接到为您导入这些函数的 LIB 文件,则可以使用 LoadLibraryGetProcAddress。 (虽然如果你有导入​​库并且可以链接到它,你为什么要手动加载这些函数?)

如果您有 DbgHelp.lib 导入库,请使用它!如果不负责任地完成,手动加载功能很容易出错。谨慎使用!

// Type definition for a function pointer that can call the function
typedef BOOL (WINAPI *StackWalk64_func)
(
    DWORD,
    HANDLE,
    HANDLE,
    LPSTACKFRAME64,
    PVOID,
    PREAD_PROCESS_MEMORY_ROUTINE64,
    PFUNCTION_TABLE_ACCESS_ROUTINE64,
    PGET_MODULE_BASE_ROUTINE64,
    PTRANSLATE_ADDRESS_ROUTINE64
);

// Within a function . . .

HMODULE hDbgHelpDll = LoadLibrary(TEXT("DbgHelp.dll"));
if (hDbgHelpDll == NULL)
{
    // handle error and return
}

StackWalk64_func funStackWalk64
    = (StackWalk64_func)GetProcAddress(hDbgHelpDll, "StackWalk64");

if (funStackWalk64 == NULL)
{
    // handle error and return
}

// funStackWalk64 is valid and ready to use

现在您可以像函数StackWalk64 一样调用funStackWalk64,并在该位置传递函数指针。使用完库后,应该释放模块句柄:

FreeLibrary(hDbgHelpDll);

【讨论】:

    【解决方案2】:

    请阅读:http://www.learncpp.com/cpp-tutorial/a1-static-and-dynamic-libraries/

    与导入库的隐式链接(使用 .lib)

    在这种情况下,静态库是一个“导入库”,它自动执行确定 DLL 中有效函数的过程。这称为隐式动态链接

    显式链接

    如果你不想使用导入库,你必须自己确定所有函数,创建相应的指向过程地址的指针,然后使用它们。 通常在您的客户端代码中有一些 InitDLL() 函数,它会执行此操作。

    见:https://msdn.microsoft.com/de-de/library/64tkc9y5.aspx

    “GetProcAddress”函数可用于获取函数的句柄并调用它。

    这称为显式动态链接,还需要在 Windows 上调用 LoadLibrary() 和 FreeLibrary()。

    更多信息:http://www.equestionanswers.com/dll/what-is-implicit-and-explicit-linking-in-dynamic-loading.php

    Linux 上的显式链接

    对于 linux/unix,情况有所不同。如果你想阅读:http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

    【讨论】:

    • 还需要在 Windows 上调用 LoadLibrary() 和 FreeLibrary()。 - 所以基本上这就是 import library 在做什么?它怎么知道.dlls 的路径?
    • 是的或多或少,这就是导入库的用途......主要区别在于您可以准确定义何时加载库并释放它以及引用哪些函数。在 Windows 上,按此处所述搜索 dll:msdn.microsoft.com/en-us/library/7d83bc18.aspx
    • 我是 OP :)。谢谢!另外,当我将代码打包到一个库中时,是否会为.dll生成相应的导入库?
    • 对不起,使用的是我没有看到原帖的应用程序。你是什​​么意思?如果你创建一个静态库?静态库,如果它使用 DLL,仍然需要最终的可执行文件也链接导入库并让 dll 可检测。
    • 我的意思是我写了一个函数sum。现在我想把它包装成一个动态库(my.dll)供其他人使用。但是我不希望别人使用LoadLibrary,所以我需要为他们提供import library文件my.lib。这个my.lib会和my.dll一起自动生成吗?
    【解决方案3】:

    通常(特别是在 Visual C++ 中)带有dlllib 文件是所谓的“导入库”。这意味着库中没有实际的函数体;它只是为了安抚链接器并指示它生成一个 EXE(或 DLL),该 EXE(或 DLL)将在加载时间使用第一个 dll

    在这种情况下也是如此。由于您无权访问DbgHelp 的源代码,因此您可以将其构建为真正的静态库,因此您需要在链接时使用小型导入库并在加载/运行时使用 dll 文件。

    注意:整个链接和动态链接的概念和机制显然比我在这里讨论的要复杂得多。因此,上面的解释非常狭窄且针对您的问题。

    【讨论】:

    • 谢谢,我现在明白了。那么如果一个some.dll没有对应的导入库some.lib怎么办呢?
    • 哦,我错过了你问题的那一部分。查看其他答案(@MABVT 提供)以了解这一点。
    猜你喜欢
    • 1970-01-01
    • 2018-06-03
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    相关资源
    最近更新 更多