【问题标题】:`__declspec(dllexport) extern std::string foo;` not found by linker`__declspec(dllexport) extern std::string foo;` 没有被链接器找到
【发布时间】:2016-09-29 23:17:01
【问题描述】:

我遇到了与此处提到的相同的问题: Protobuf - Refuses to link vs2013 or vs2015

我发现generated_message_util.h中的这两行可能会导致这个问题:

__declspec(dllexport) extern const ::std::string* empty_string_;
__declspec(dllexport) extern ProtobufOnceType empty_string_once_init_;

见:https://github.com/google/protobuf/blob/master/src/google/protobuf/generated_message_util.h#L80

我对关键字 extern 不是很熟悉,但最后尝试使用该库的链接器找不到这些变量的两个定义,这些变量在 generated_message_util.cc 中完成.

const ::std::string* empty_string_;
GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_);

void InitEmptyString() {
  empty_string_ = new string;
  ...
}

请参阅:https://github.com/google/protobuf/blob/master/src/google/protobuf/generated_message_util.cc#L51 和以下行。

有人知道这个问题的好解决方法吗?

【问题讨论】:

    标签: c++ extern dllexport


    【解决方案1】:

    确保您的编译器标志和定义的预处理器符号设置正确。

    __declspec(dllexport) 应设置为创建 DLL,并且您的代码需要包含定义。如果要使用DLL,则需要__declspec(dllimport)

    请参阅port.h文件 (src/google/protobuf/stubs/port.h) 了解 LIBPROTOBUF_EXPORT 的定义。它依赖于LIBPROTOBUF_EXPORTS,因此如果您想创建 DLL,请确保LIBPROTOBUF_EXPORTS 定义。如果您想使用 DLL,请确保LIBPROTOBUF_EXPORTS 定义。

    为了识别问题,您可以在您的项目中插入以下代码:

    #ifdef LIBPROTOBUF_EXPORTS
    #error defining LIBPROTOBUF_EXPORTS only allowed on DLL creation!
    #endif
    
    #ifndef PROTOBUF_USE_DLLS
    #error defining PROTOBUF_USE_DLLS is required for DLL usage!
    #endif
    

    如果你的符号定义错误,会导致编译错误。然后您仍然需要修复您的项目设置,直到满足条件。鉴于目前的信息,我无法为您提供帮助。

    如果条件没有触发错误并且问题仍然存在,则可能还有其他问题,值得更详细地研究。

    【讨论】:

    • LIBPROTOBUF_EXPORTSPROTOBUF_USE_DLLS 在库项目预处理器设置中定义。使用这个库的应用程序没有定义它们。
    • @MatthiasLochbrunner 那么你的问题标题没有多大意义...... LIBPROTOBUF_EXPORT 不应扩展到 __declspec(dllexport) 除非 PROTOBUF_USE_DLLSLIBPROTOBUF_EXPORTS 已定义。请重新检查。
    • @grek40 是的,我只在这里修改了代码以便更好地阅读。 PS。现在我使用LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { return ""; } 的坏技巧,这似乎有效。如果您知道更好的解决方案。我愿意接受任何批准。
    • @MatthiasLochbrunner 查看我的编辑,以了解使问题可见的方法。不要使用 hack,只需确保符号的定义与您想象的一样。
    猜你喜欢
    • 1970-01-01
    • 2011-11-23
    • 2012-07-14
    • 2016-02-18
    • 2018-08-05
    • 2023-01-26
    • 2022-01-05
    • 2015-02-24
    • 2016-03-25
    相关资源
    最近更新 更多