dll从静态链接库导出函数符号

Posted

技术标签:

【中文标题】dll从静态链接库导出函数符号【英文标题】:Dll export symbol of function from static linked library 【发布时间】:2018-03-30 21:38:29 【问题描述】:

我在 Dll 中包装了一个静态库来隐藏很多实现的东西,因为只需要 4-5 个函数并避免提供所有第三方库和许多头文件。我似乎在将函数从静态库导出到 dll 时遇到问题。 静态库具有类似于下面的设置类/结构

struct FooSettings

   bool Read(const std::string& file); // implemented in .cpp
   bool Write(const std::string& file); // implemented in .cpp
   // rest members, just plain types
;

在Dll端

#include "FooSettings.h"

#if defined(WIN32) || defined(_WIN32)
    #if defined(LIB_EXPORT)
        // DLL Build, exporting symbols
        #define LIB_API __declspec(dllexport)
    #elif LIB_IMPORT
        // DLL use, importing symbols
        #define LIB_API __declspec(dllimport)
    #endif
#endif

#ifndef LIB_API
    #define LIB_API
#endif

class LIB_API LibSDK

public:
    LibSDK();
    ~LibSDK();

    FooSettings get() const noexcept;
    void set(const FooSettings& settings) const noexcept;

    void dummy() 
    
        foo.Read("");
    

private:
    // etc...
;

我可以在“客户端”端拨打dummy(),没有任何问题 但下面的代码会导致无法解析的符号

FooSettings foo;
foo.Read("");

我原以为 FooSettings:Read 至少会被导出,因为它是虚拟函数的一部分。我错过了什么吗?我的偏好是在没有虚拟函数的情况下导出它,但我似乎无法让它工作。

【问题讨论】:

如何导出函数?为什么你的代码中没有__declspec(dllexport)?你在使用导出文件吗?您应该发布完整的代码。此外,如果您需要导出Read 函数,您可以在不导出dummy 的情况下执行此操作。两者之间没有任何关系。 @Ivan 我已经编辑了我的帖子以展示我如何导出类,正如你所说,它几乎是通过定义 LIB_EXPORT 使用 __declspec(dllexport)。问题出在静态库中的类函数 所以你正在导出一个LibSDK 类(tihs 包含dummy 函数,但你没有导出FooSettings。你希望FooSettings 自动导出吗?或者你想要导出LibSDK而不导出FooSettings?在这种情况下dummy不应该是inline函数。 @Ivan,FooSettings 函数是静态库的一部分,因此没有必要导出它。据我所知,来自blogs.msdn.microsoft.com/oldnewthing/20140321-00/?p=1433,您要么需要一个 .def 文件,要么需要创建一个虚拟函数。所以在这种情况下,我正在尝试一个虚拟函数。我假设由于虚拟函数可以看到调用读取和写入的符号,那么我应该能够从“客户端”端这样做,但这会导致符号无法解析。当然,虚拟函数在 .cpp 文件中,但在这里为了简洁起见,我将它们全部添加在一起。 我应该说是的,我知道如果我在 Dll 项目中添加所有静态库文件并导出 FooSettings 类,那么一切都可以正常工作。我只是想知道是否可以避免这样做并强制以不同的方式添加符号。我还读到您可以使用链接器属性中的 \Includes 来做到这一点,但我无法弄清楚语法。 【参考方案1】:

回到这一切,答案实际上是我没想到的静态库构建中的#define LIB_EXPORT。

我认为静态 .lib 文件不需要这样的东西,因为它们只是一组目标文件,因此不需要将它们标记为导出。显然,如果您想将静态库中的函数导出到包装器 dll,则需要它。

【讨论】:

以上是关于dll从静态链接库导出函数符号的主要内容,如果未能解决你的问题,请参考以下文章

如何防止静态库中的所有符号加载以及为什么在链接静态库时导出相同.o文件中的其他符号进行测试

动态链接库.so和静态链接库.a

[转载] 动态链接库dll的 静态加载 与 动态加载

如何从一个动态链接库DLL中查看接口函数

静态链接库

静态链接库和动态链接库