代码之家  ›  专栏  ›  技术社区  ›  SMGreenfield

从mydylib调用带有std::string参数的成员函数会产生“未定义符号”错误

  •  0
  • SMGreenfield  · 技术社区  · 9 年前

    当试图与我用Xcode 6.3.2构建的动态库链接时,我对参数为std::string的类函数的所有调用都拒绝链接:

    Undefined symbols for architecture x86_64:
      “MyClass::Bogus(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)”,…
    

    包含dylibs.h文件,公共类成员的原型为:

    int Bogus(std::string& aStringRef, bool verbose);
    

    有趣的是,如果我将第一个std::string参数的类型更改为long(并使用long作为第一个参数调用它),则不会出现链接错误。所以我知道我肯定和我建立的dylib有联系。

    对于我的dylib,Apple LLVM 6.1 C++标准库设置为默认值(libstdc++)。

    我调用的代码本身是一个.dylib,它不是从Xcode编译和链接的,而是完全从makefile编译和链接。用于从该makefile编译的c++版本为:

    Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
    Target: x86_64-apple-darwin14.4.0
    Thread model: posix
    

    我觉得可疑的一点是,调用代码是使用“-std=c++1y”编译的,这可能是使用c++14的标准库。为调用程序链接的标准库与我选择用于构建dylib的标准库之间是否存在冲突?(我的dylib代码是用编译器方言=GNU++98编译的)

    1 回复  |  直到 9 年前
        1
  •  2
  •   Community Ian Goodfellow    7 年前

    很难在不同的二进制模块之间传递标准库对象,因为它们的二进制表示和实现细节没有标准化。

    要使其工作,您需要确保所有模块都使用相同的编译器、标准库实现和所有相关的编译设置(异常、迭代器调试等)……这基本上违背了拥有动态库的初衷。

    在传递数据时,您应该坚持使用简单的指针(c字符串、数据缓冲区),或者引入一些自定义的、更透明的数据类型。

    有关一些具体解决方案,请参见以下答案:

    Passing std::string in a library API

    Passing reference to STL vector over dll boundary