gpt4 book ai didi

c++ - 使用 -fno-rtti 编译的共享库的子类类

转载 作者:可可西里 更新时间:2023-11-01 17:57:01 26 4
gpt4 key购买 nike

我正在尝试从使用 -fno-rtti 编译的共享库进行子类化。不幸的是,我的代码库中的其他库需要 -frtti。结果我收到链接错误,因为父类(super class)没有类型信息结构。

正常编译收到的错误:

out.o: in function typeinfo for MyClass:myclass.cpp(.data.rel.ro.<cpp magic>): error: undefined reference to 'typeinfo for NetlinkListener'

我想要子类化的类是 libsysutils 中的一个 android 类(为了空间而剪掉了一点):

class NetlinkListener : public SocketListener {
char mBuffer[64 * 1024];
int mFormat;

public:
static const int NETLINK_FORMAT_ASCII = 0;
static const int NETLINK_FORMAT_BINARY = 1;

NetlinkListener(int socket);
NetlinkListener(int socket, int format);
virtual ~NetlinkListener() {}

protected:
virtual bool onDataAvailable(SocketClient *cli);
virtual void onEvent(NetlinkEvent *evt) = 0;
};

我的 stub 看起来像:

class MyClass: public NetlinkListener {

public:
MyClass();
virtual ~MyClass();

int start();
int stop();

protected:
virtual void onEvent(NetlinkEvent *evt);
};

MyClass 中的所有方法都已实现(作为空 stub )

我无法编译共享库 -frtti。有什么办法可以解决这个问题吗?

最佳答案

1) 对于简单的情况,您可以只创建一个接口(interface)的 C 包装器(在没有 RTTI 的情况下构建)。然后,您可以在支持 RTTI 的程序中使用 C 接口(interface),前提是您将它​​们视为来自支持 RTTI 的程序的抽象 C 类型。

2) 使用 RTTI 编译库正是您应该做的(或供应商的要求),除非有充分的理由禁用 RTTI(例如,您正在工作不应使用异常的域,例如内核、驱动程序或其他一些无异常区域——或内存紧张的区域。

3) 更改您的库,使其不使用 dynamic_cast、异常、typeid 运算符或任何导致问题的内容,并在禁用 RTTI 的情况下重建。与 1 类似,您可以将其作为一个单独的抽象库,具体取决于程序的组织方式。

4a) 下一个选项是永远不要引用对象的类型信息(例如,不要 dynamic_cast 或 throw 它)——这可能会很痛苦。这将消除引用类型信息的链接器错误。

4b) 创建一个内部类可能是最简单的方法(假设有一些方法您必须覆盖,并且有一些类型您必须与您的 rtti 相关程序交互)。您可以创建一个类型 (inner),它继承自其 lib 的类型并执行必要的覆盖,但随后通过其他一些类层次结构回调(其他层次结构可以免费使用 rtti)。现在,inner 类的虚拟导出被放置在 rtti disabled 的 TU 中(因为否则它将隐式引用其基类的类型信息)。然后您可以轻松地隔离类型信息依赖并构建一个使用异常之类的层次结构——这个层次结构使用 inner 类型作为值。当然,如果可行,这都是实现定义——您需要了解 RTTI 和 vtables 是如何针对您的目标平台构建的(请参阅 ABI 引用)。即使省略 RTTI 也会偏离标准 C++。没有任何信息表明符号的存在会导致正确构建您的 vtable 和在没有这些功能的情况下编译的基类的类型信息。

也就是说,1 和 2 是您的安全选项,3 在 no-rtti 平台扩展的范围内(安全),4 是一种可以在任何系统或仅在某些系统上免费工作的方法。

说明 4b

class MyClass // << cast me. throw/catch me. get my mangled name,
// but put my family's virtual exports in a TU with RTTI enabled
: public MyRTTIEnabledFamily {
public:
MyClass() : d_inner(*this) {}
virtual ~MyClass();
private:
void cb_onEvent(NetlinkEvent * evt) {
// no-rtti suggests exceptions may not be available,
// so you should be careful if your program throws.
someInfo = evt->getInfo();
}
private:
// non-rtti hierarchy
class t_inner : public NetlinkListener {
public:
t_inner(MyClass& pMyClass) : NetlinkListener(), d_myClass(pMyClass) {
}

virtual ~t_inner(); // << put your virtual exports in a TU with RTTI disabled.
// one out of line virtual definition is necessary for most compilers
private:
virtual void onEvent(NetlinkEvent * evt) {
// how the callback to your imp actually happens
this->d_myClass.cb_onEvent(evt);
}
private:
MyClass& d_myClass;
};
private:
t_inner d_inner; // << don't do anything with my type info -- it does not exist.
};

关于c++ - 使用 -fno-rtti 编译的共享库的子类类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15101859/

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