1) Pour les cas simples, vous pouvez simplement créer un wrapper C de l'interface (construit sans RTTI). Vous pouvez alors utiliser l'interface C dans les programmes compatibles avec la RTTI, à condition de les traiter comme des types C abstraits à partir de votre programme compatible avec la RTTI.
2) La compilation de la bibliothèque avec RTTI est exactement ce que vous devrait (ou à la demande du vendeur), à moins qu'il y ait une très bonne raison de désactiver le RTTI (par exemple, vous travaillez dans un domaine où les exceptions ne devraient pas être utilisées, comme un noyau, des pilotes, ou une autre zone sans exception -- ou lorsque la mémoire est restreinte).
3) Modifiez votre bibliothèque pour ne pas utiliser dynamic_cast, les exceptions, l'opérateur typeid, ou tout ce qui cause le problème et reconstruisez avec RTTI désactivé. Comme pour le point 1, vous pouvez en faire une bibliothèque d'abstraction séparée, en fonction de la façon dont le programme est organisé.
4a) L'option suivante est de ne jamais référencer l'information de type pour l'objet (par exemple, ne pas faire de dynamic_cast ou ne pas le lancer) -- et cela peut être pénible. Cela supprimera les erreurs du linker concernant les informations de type référencées.
4b) Il peut être plus facile de créer une classe interne (supposons qu'il y ait des méthodes que vous devez surcharger, et qu'il y ait des types que vous devez interfacer avec vos programmes dépendants de la rtti). Vous pouvez créer un type ( inner
) qui hérite du type de leur lib et effectue les surcharges nécessaires, mais rappelle ensuite à travers une autre hiérarchie de classes (l'autre hiérarchie est libre d'utiliser rtti). Aujourd'hui, le inner
Les exportations virtuelles de la classe sont placées dans une UT avec rtti handicapé (car sinon, il fera implicitement référence aux informations de type de sa classe de base). Ensuite, vous pouvez facilement mettre en quarantaine la dépendance de l'information de type et construire une hiérarchie qui utilise des choses comme les exceptions -- cette hiérarchie utilise cela inner
comme valeur. Bien entendu, si qui fonctionne, c'est tout la mise en œuvre définie -- Vous devez comprendre comment RTTI et vtables sont structurés pour les plates-formes que vous ciblez (voir les références ABI). Même l'omission de RTTI est une déviation par rapport au C++ standard. Il n'existe aucune information indiquant que la présence d'un symbole entraînera une construction correcte de vos tables virtuelles et des informations de type d'une base qui a été compilée sans ces caractéristiques.
Cela dit, les points 1 et 2 sont des options sûres, le point 3 relève de l'extension de la plate-forme no-rtti (sûre) et le point 4 est une approche qui est libre de fonctionner sur aucun système ou sur certains systèmes seulement.
Illustration 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.
};