gpt4 book ai didi

c++ - 来自共享库的非模板基的模板子类导致 'class' 链接错误的 undefined symbol 类型信息

转载 作者:行者123 更新时间:2023-11-28 01:49:31 25 4
gpt4 key购买 nike

总结

我构建了一个共享库,其中包含一个非模板类,我从中派生了一个链接到该库的项目中的模板类。

当我编译/链接引用项目时,我收到以下链接错误:

Undefined symbols for architecture x86_64:
"typeinfo for BaseClass", referenced from:
typeinfo for DerivedClass<int> in main.o

typeinfo 实际上指的是什么?为了更深入地挖掘,我无法找到有关它的信息。

该错误似乎暗示 BaseClass 应该具有某种类型的信息,但我不明白缺少什么。

此外,我知道此错误通常伴随着 vtable for ... 链接错误,通常是当您忘记为虚拟方法提供定义或将其定义为纯虚拟时,但我相信我在下面的 我尝试过的事情 中用 #1 排除了这一点,因为如果 foo()main.cpp 将不会编译' s 的定义无法从图书馆获得。

来源

我已经将这些类提炼为以下仍然重现问题的类:

BaseClass.h(我要链接的共享库的一部分)

#ifndef BASECLASS_H_
#define BASECLASS_H_

class BaseClass
{
protected:
int myField;

public:
BaseClass();
virtual ~BaseClass() {}

virtual void foo();
};

#endif

BaseClass.cpp(编译成生成的 dylib)

#include <iostream>
#include "BaseClass.h"

__attribute__((visibility("default")))
BaseClass::BaseClass()
: myField(0)
{

}

__attribute__((visibility("default")))
void BaseClass::foo()
{
std::cout<<myField<<std::endl;
}

DerivedClass.h(在与库链接的单独项目中)

#ifndef DERIVEDCLASS_H_
#define DERIVEDCLASS_H_

#include <BaseClass.h>

template <typename T>
class DerivedClass : public BaseClass
{
protected:
T data;

public:
DerivedClass(T data) : data(data) {}
virtual ~DerivedClass() {}
};

#endif

ma​​in.cpp(表示问题的引用 DerivedClass)

#include "DerivedClass.h"

int main()
{

DerivedClass<int> derived(0);
derived.foo();

return 0;
}

构建命令

共享库

编译:

g++ -O3 -Wall -c -fmessage-length=0 -fvisibility=hidden -MMD -MP -MF"src/BaseClass.d" -MT"src/BaseClass.o" -o "src/BaseClass.o" "../src/BaseClass.cpp"

链接:

g++ -Xlinker -install_name -Xlinker "@rpath/libmylibrary.dylib" -dynamiclib -o "libmylibrary.dylib" ./src/BaseClass.o

引用项目

编译:

g++ -I"/code/myproject/deps/mylibrary/include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cpp"

链接:

g++ -L"/code/myproject/deps/mylibrary/bin" -Xlinker -rpath -Xlinker "@loader_path" -o "myproject"  ./src/InternalBaseClass.o ./src/main.o   -lmylibrary

环境信息

  • 操作系统: macOS 10.11.6 (El Capitan)
  • 编译器:Apple LLVM 版本 8.0.0 (clang-800.0.42.1)(g++ 链接到此)
  • 链接器:ld

我尝试过的事情

我已经做了这些事情,试图将原因缩小到具体是由于子类是模板,而基类来自共享库。

  1. 确保 BaseClass 可以被单独引用。 通过更改 main.cpp 以包含 BaseClass 并在 main() 中实例化它并调用 foo() 来测试它> 就可以了。编译和链接没有错误。

  2. 派生自内部基类而不是共享库。 通过创建一个名为 InternalBaseClass 的类进行测试,该类具有完全相同的源,除了定义文件中的 __attribute__ 行,将其包含在 DerivedClass header 中代替包含 BaseClass,并在 DerivedClass 的类声明中将其指定为父类。编译和链接没有错误。

  3. 使 DerivedClass 成为非模板。 通过删除 DerivedClass 中的模板声明并将对参数化类型 T 的引用替换为 int 来对此进行测试。这编译和链接没有错误。

提前致谢!

最佳答案

看起来您正在使用“-fvisibility=hidden”构建共享库并使用 __attribute__((visibility("default"))) 标记导出的函数,但是为了导出 RTTI,您需要使用 __attribute__((visibility("default"))) 标记导出的类。来自 gcc referece :

Note that the type visibility is applied to vague linkage entities associated with the class (vtable, typeinfo node, etc.). In particular, if a class is thrown as an exception in one shared object and caught in another, the class must have default visibility. Otherwise the two shared objects are unable to use the same typeinfo node and exception handling will break.

关于c++ - 来自共享库的非模板基的模板子类导致 'class' 链接错误的 undefined symbol 类型信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43562659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com