Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 仅当类重写方法时,在动态加载的共享库中实例化的类的XCode 4.3/4.4 typeinfo才会丢失_C++_Xcode_Llvm_Clang_Dynamic Cast - Fatal编程技术网

C++ 仅当类重写方法时,在动态加载的共享库中实例化的类的XCode 4.3/4.4 typeinfo才会丢失

C++ 仅当类重写方法时,在动态加载的共享库中实例化的类的XCode 4.3/4.4 typeinfo才会丢失,c++,xcode,llvm,clang,dynamic-cast,C++,Xcode,Llvm,Clang,Dynamic Cast,我在运行时加载的共享库中实例化的对象上使用dynamic_cast遇到了一个问题,但前提是该类包含重写另一个方法的方法 我使用的是Xcode 4.3和“Apple LLVM 3.1编译器”,我在linux上用gcc和clang编译了相同的代码,没有这个问题,所以我假设这是Xcode中的一个编译器错误,但是以前有人看到过吗 假设类定义位于名为“test3.h”的标题中 假设实现代码位于名为“test3.cpp”的源文件中的静态库中 假设源文件test2.cpp中有一个简单的动态库 #include

我在运行时加载的共享库中实例化的对象上使用dynamic_cast遇到了一个问题,但前提是该类包含重写另一个方法的方法

我使用的是Xcode 4.3和“Apple LLVM 3.1编译器”,我在linux上用gcc和clang编译了相同的代码,没有这个问题,所以我假设这是Xcode中的一个编译器错误,但是以前有人看到过吗

假设类定义位于名为“test3.h”的标题中

假设实现代码位于名为“test3.cpp”的源文件中的静态库中

假设源文件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;
}
#包括“test3.h”
#包括
#包括
int main()
{
自动库(dlopen(“libtest2.dylib”,RTLD_NOW | RTLD_GLOBAL));
自动a1(dlsym(lib,“get1”);
自动a2(dlsym(lib,“get2”);
自动f1((c1*(*)())a1);
自动f2((c1*(*)())a2);
自动o1(f1());
自动氧气(f2());
自动d1(动态_-cast(o1));
自动d2(动态_铸造(o2));
自动结果1(d1!=0);
自动结果2(d2!=0);

std::cout我认为这个问题的原因有两个。首先,动态强制转换在RTTI对象上使用相等比较。其次,有两个对象:一个在主线中,一个在动态库中

此问题的解决方法应该是确保要共享的类位于单独的动态链接库中,并且由主线和所有其他共享库链接到

实际上,这是库/编译器中的一个bug:它不应该使用指针相等来进行动态类型比较


哎呀,我试过了,但它并没有解决我的问题(g++过去也把这个搞砸了)。
奇怪的是,我在另一个库中正确地捕获了一个异常,重新调用它,通过基类指针正确地捕获它,但是动态_cast失败了。所以我的建议似乎不起作用(在OSX上)抱歉,

如果C++要将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
#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;
}
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