只有当类重写方法时,在动态加载的共享库中实例化的类才会丢失XCode 4.3/4.4 typeinfo
XCode 4.3/4.4 typeinfo is lost for class instantiated in a dynamically loaded shared library only if class overrides a method
我在运行时加载的共享库中实例化的对象上使用dynamic_cast遇到了一个问题,但前提是该类包含覆盖另一个方法的方法。
我将Xcode 4.3与"Apple LLVM 3.1编译器"一起使用。我在linux上用gcc和clang编译了相同的代码,但没有问题,所以我认为这是Xcode中的编译器错误,但以前有人见过吗?
假设类定义在名为"test3.h"的头中
#pragma once
class c1
{
public:
virtual ~c1 ();
virtual void foo ();
};
class c2 : public c1
{
public:
void foo () override;
};
class c3 : public c1
{
public:
};
假设实现代码位于名为"test3.cpp"的源文件中的静态库中
#include "test3.h"
c1::~c1 ()
{
}
void c1::foo ()
{
}
void c2::foo ()
{
}
假设一个名为test2.cpp 的源文件中有一个简单的动态库
#include "test3.h"
extern "C"
c1 * get1 ()
{
return new c2;
}
extern "C"
c1 * get2 ()
{
return new c3;
}
假设源文件test1.cpp 中有一个简单的可执行应用程序
#include "test3.h"
#include <dlfcn.h>
#include <iostream>
int main ()
{
auto lib (dlopen ("libtest2.dylib", RTLD_NOW | RTLD_GLOBAL));
auto a1 (dlsym (lib, "get1"));
auto a2 (dlsym (lib, "get2"));
auto f1 ((c1 * (*) ())a1);
auto f2 ((c1 * (*) ())a2);
auto o1 (f1 ());
auto o2 (f2 ());
auto d1 (dynamic_cast <c2 *> (o1));
auto d2 (dynamic_cast <c3 *> (o2));
auto result1 (d1 != 0);
auto result2 (d2 != 0);
std::cout << result1 << std::endl;
std::cout << result2 << std::endl;
}
运行测试程序时,result1为false,而result2为true。我希望result1和result2都是真的。
有人看到这一点吗?或者能想出一个变通办法吗?
我认为这个问题的原因有两个。首先,动态强制转换在RTTI对象上使用相等比较。其次,有两个:一个在主线中,一个在动态库中。
这个问题的解决方法应该是确保要共享的类在一个单独的动态链接库中,并且由主线和所有其他共享库链接到。
实际上,这是库/编译器中的一个错误:它不应该使用指针相等来进行动态类型比较。
哎呀。我试过这个,但它并没有解决我的问题(g++过去也把它搞砸了)。奇怪的是,我在另一个库中正确地捕获了一个异常,重新思考它,通过基类指针正确地捕获它,但dynamic_cast失败了。因此,我的建议(在OSX上)似乎不起作用。很抱歉
如果您打算将c++类的实现代码从.dylib
传递到另一个应用程序,则不能使用静态库来实现这些类——您必须使用共享对象。
原因是在链接时,您最终会在libtest2.dylib
和test1
中获得类型信息的私有副本;并且它们将彼此不兼容。
如果要使其工作,则需要在链接到libtest2.dylib
和应用程序test1
的.dylib
中从test3.cpp/h
导出类。
示例Makefile
:
CXX=clang
CXXFLAGS=-std=c++11
all: libshlib.dylib libtest2.dylib test1
clean:
rm -f *.o test1 *.dylib
test3.o: test3.cpp test3.h
$(CXX) $(CXXFLAGS) -c -fPIC test3.cpp -o test3.o
libshlib.dylib: test3.o
$(CXX) $(CXXFLAGS) -fPIC -shared test3.o -o $@ -lstdc++
test2.o: test2.cpp test3.h
$(CXX) $(CXXFLAGS) -c -fPIC test2.cpp -o test2.o
libtest2.dylib: libshlib.dylib test2.o
$(CXX) $(CXXFLAGS) -o $@ -shared test2.o -lstdc++ -L. -lshlib
test1: test1.o test3.h
$(CXX) $(CXXFLAGS) -o $@ test1.o -lstdc++ -L. -lshlib
test1.o: test1.cpp test3.h
$(CXX) $(CXXFLAGS) -c -o $@ test1.cpp
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 Xcode 中实例化后的显式专用化
- XCode 警告"此处需要实例化变量'Singleton:<Foo>:_instance',但没有可用的定义
- 只有当类重写方法时,在动态加载的共享库中实例化的类才会丢失XCode 4.3/4.4 typeinfo
- 在XCode/Clang中使用std::shared_ptr实例化std::map出错