使用Qt(5.12,带有r18b,clang),我创建了一个导出某些类的共享库。然后,我创建一个在这些类之间执行一些dynamic_cast
的程序。在带有VS 2015的Windows下,它可以完美运行(下面没有发布__declspec
)。在使用clang的Android下,dynamic_cast
失败。我可以阅读很多主题,例如:
dynamic_cast an interface from a shared library which was loaded by lt_dlopen(libtool) doesn't work
因此,我尝试向我的图书馆项目中添加一些标志,尝试了许多事情(不确定哪一个起作用):
QMAKE_LFLAGS += -Wl,--export-dynamic
QMAKE_LFLAGS += -Wl,-E
QMAKE_LFLAGS += -Bsymbolic
但是,即使我看到链接上使用了这些标志,它仍然会失败。
这是我的MCVE:
dynamiccast_lib.pro :
TARGET = dynamiccast_lib
QT -= core
QT -= gui
QMAKE_LFLAGS += -Wl,--export-dynamic
QMAKE_LFLAGS += -Wl,-E
QMAKE_LFLAGS += -Bsymbolic
TEMPLATE = lib
CONFIG += shared
SOURCES += \
C:/dev/vobs_sde/public/lib/dynamiccast_lib/src/dynamiccast_lib.cpp
HEADERS += \
C:/dev/vobs_sde/public/lib/dynamiccast_lib/ifc/dynamiccast_lib.h
INCLUDEPATH += \
C:/dev/vobs_sde/public/lib/dynamiccast_lib/ifc
dynamiccast_prg.pro :
TARGET = dynamiccast_prg
QT -= core
QT -= gui
QMAKE_LFLAGS += -Wl,--export-dynamic
QMAKE_LFLAGS += -Wl,-E
QMAKE_LFLAGS += -Bsymbolic
TEMPLATE = app
SOURCES += \
C:/dev/vobs_sde/public/prg/dynamiccast_prg/src/main.cpp
INCLUDEPATH += \
C:/dev/vobs_sde/public/prg/dynamiccast_prg/inc \
C:/dev/vobs_sde/public/lib/dynamiccast_lib/ifc
LIBS += -l$$OUT_PWD/../../lib/dynamiccast_lib/libdynamiccast_lib.so
PRE_TARGETDEPS += $$OUT_PWD/../../lib/dynamiccast_lib/libdynamiccast_lib.so
dynamiccast_lib.h :
#pragma once
#include <iostream>
class BaseClass
{
public:
BaseClass()
{
}
virtual void show() = 0;
};
class DerivedClass : public BaseClass
{
public:
DerivedClass( int attr ) : attr( attr )
{
}
void show() override
{
std::cout << attr << std::endl;
}
private:
int attr;
};
class DYNAMICCAST_LIB_API Helper
{
public:
static BaseClass* CreateIntObject( int attr );
};
dynamiccast_lib.cpp :
#include "dynamiccast_lib.h"
BaseClass* Helper::CreateIntObject( int attr )
{
return new DerivedClass( attr );
}
main.cpp:
#include "dynamiccast_lib.h"
#include <iostream>
int main( int argc, char* argv[] )
{
BaseClass* ptr = Helper::CreateIntObject(3);
DerivedClass* casted = dynamic_cast< DerivedClass* >( ptr );
casted->show();
return 0;
}
此代码崩溃,因为casted
为NULL。如何使这个简单的代码在Android下运行?
答案 0 :(得分:0)
经过一些调查,我可以自己解决此问题。根本不需要添加任何链接标志。通过在dynamic_cast
中添加virtual
方法并在BaseClass
中实现它,我可以得到此修复(dynamiccast_lib.cpp
工作)。
添加到dynamiccast_lib.h
:
virtual ~BaseClass;
添加到dynamiccast_lib.cpp
:
BaseClass::~BaseClass
{
}
这使得dynamic_cast
正好从程序中开始工作。任何virtual
函数都可以解决此问题(不仅是析构函数),而且实现必须在源文件中,而不能在头文件中(否则dynamic_cast
仍然会失败)。令人惊讶,但这就是我通过测试观察到的结果。