Dynamic_cast<T>(x) - Unix Segfault [Probleme] - C++ - Programmation
Marsh Posté le 11-12-2008 à 23:12:30
Bon voila problème résolue.
C'est juste que Unix c'est moisi ! (ce n’est pas un troll, après deux ans dessus, j'apprécie toujours pas ...), même si Windows et tous ces #define …..
Passons aux choses sérieuses, je développe au cas où ca pourrait servir.
En faite, j'avais oublié de préciser que l'abstraction Windows / Unix se faisait au niveau du chargement / déchargement de librairies dynamiques (.so et .dll)
Le problème est bien au niveau de Unix, quand il créer les .so, il perd des information (comme l'héritage, comme quoi Unix...), qui ne lui permet pas de savoir que le type de note objet actual est un objet qui hérite de la class X.
Donc il faut impérativement utiliser un reinterpret_cast<T>().
Bon voila, si ca peut aider quelqu’un à l’avenir !
:hello :
Marsh Posté le 12-12-2008 à 07:21:18
kaiser52 a écrit : Bon voila problème résolue. |
Mais tu racontes n'importe quoi ...
Y a pas à de flag à activer, sauf pour désactiver les RTTI ... si ça segfault, c'est probablement que actual ou autre vaut 0. Sort ton debugger et tu trouveras. Y a rien de mystique.
Et c'est certainement pas en CFLAGS += -fno-rtti en disant au compilateur __C__ de désactiver les rtti que ça va mieux marcher.
Reprend ça tranquillement. Les RTTI sont bien exportées dans les DSO.
Marsh Posté le 12-12-2008 à 09:36:49
Peut-être que ce serait une donnée, qui serait supposément initialisée à null par défaut, alors que ce ne serait pas le cas, sauf dans certaines circonstances.
Marsh Posté le 12-12-2008 à 09:54:06
kaiser52 a écrit :
|
Sauf que tu dis du caca :€
T'as un bug ailleurs et c'est tout.
EDIT
Marsh Posté le 12-12-2008 à 10:05:31
Tu as du quotter le mauvais post.
Dans celui la je ne parle plus de RTTI (Surtout que je me suis rendu compte qu'il n'y avait pas de rapport).
Mais il y à bien un problème avec les .so.
Être obliger d'utiliser un reinterpret_cast<T>() c'est quand même crade pour un si petit programme (pourquoi pas utiliser un cast "C" histoire de pas savoir quel cast va être appliqué).
Surtout que le dynamic_cast<T>() fonctionne très bien sur Windows, et bien sure la parti ou "ça plante" sur Unix n'est pas une parti abstraite, donc le même code sur Windows / Unix
En gros dans le programme au chargement dynamiques des librairies, on appelle une méthode GetObject() qui nous renvois un new Class_de_la_ld qui est stocké dans une map<std::string nom_de_la_ld, IInterfaceObject* pointer_sur_la_class>, ensuite nous utilisons la méthode clone() de Class_de_la_ld pour dupliquer ou recréer un objet du même type (design prototype) en fonction de la demande.
Parmi les directives, toutes les méthodes de la Class_de_la_ld doivent renvoyer un IInterface*.
Sachant que :
Class_de_la_ld hérite de IInterfaceObject qui elle même hérite de IInterface.
D'ou le probléme et l'obligation de caster.
Marsh Posté le 12-12-2008 à 10:15:27
je pencherais plus pour un bug de 3.4 qu'autre chose.
J'ai un système équivalent dans un gros projet et ca marche sans pb sous nix.
Je compile avec 4.3
Marsh Posté le 12-12-2008 à 10:21:17
Joel F >>
Je t'expose le schema :
Windows Unix
Chargement des librairies : OK OK Code Différent
( Ainsi que dans la map)
Acces aux methodes de
la Class_de_la_dl via IInterface : OK OK Code Identique
(Methodes hérité)
/*
** Contenu de toutes les variables du programme
** identique entre Unix et Windows à ce niveau du programme
*/
Cast de IInterface en IInterfaceObject OK ECHEC Code Identique
Dynamic_cast<T>() Pointer NULL
(Methodes hérité)
Cast de IInterface en IInterfaceObject OK OK Code Identique
reinterpret__cast<T>()
/*
** Contenu de toutes les variables du programme
** identique entre Unix et Windows à ce niveau du programme
*/
Acces aux methodes de
la Class_de_la_dl via IInterfaceObject OK OK Code Identique
Déchargement des librairies : OK OK Code Différent
Si le dynamic_cast<T>() marche sur Windows c'est qu'il doit marcher sur Unix.
Le reinterpret_cast<T>() permet convertir tous en tous, donc c'est normal que ça marche, et si la suite se déroule correctement c'est bien que l'objet qui est typé IInterface peut aussi être typé IInterfaceObject car il contient bien ces méthodes.
Edit :
Le probleme c'est que l'on à pas le droit de changer de version de GCC.
Marsh Posté le 12-12-2008 à 11:29:47
ca sent le foirage de gcc ça
Je vais voir à tester mon projet avec 3.4
Marsh Posté le 12-12-2008 à 11:36:29
J'ai trouvé ça :
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9433
Citation : The Segfault happens in the runtime support libs (with 3.4): |
Marsh Posté le 12-12-2008 à 12:40:06
t'es bien en -fPIC ?
g++ -c -fPIC interface.cpp
g++ -shared -o libinterface.so interface.o
g++ -L. -linterface main.cpp
LD_LIBRARY_PATH=. ./a.out
et hop tu roules.
Marsh Posté le 12-12-2008 à 12:41:34
kaiser52 a écrit : J'ai trouvé ça :
|
j'ai un version gcc 3.4.6 20060404 (Red Hat 3.4.6-8) sur RHEL4.5 aucun pb. Vérifie de bien faire comme je t'ai dit.
Marsh Posté le 12-12-2008 à 12:48:14
hum, ça sent le vainqueur -c -shared . C'est incompatible, vu que -c empêche le link, du coup tous tes symboles vers libstdc++ et donc le runtime nécessaire aux RTTI ne sont pas résolus ... boum
Marsh Posté le 12-12-2008 à 13:06:20
Bon bah merci de la tentative quand même ^^
Pour le moment je reste comme ça (avec le reinterpret_cast<T>()) vue que ça marche.
Marsh Posté le 12-12-2008 à 14:23:20
kaiser52 a écrit : Bon bah merci de la tentative quand même ^^ |
ouais je brasse du vent quoi. je me casse.
Marsh Posté le 12-12-2008 à 14:37:54
Bah tu t'es contredis tous seul
Et tu te clashe tous seul !
Je ne pige pas là !
Marsh Posté le 11-12-2008 à 09:48:41
Bonjour a tous,
Je suis actuellement en train de coder une "abstraction", mais j'ai un petit (Enfin gros) problème.
Notre programme doit fonctionner sur Windows et sur Unix.
Nos tests sur Windows se sont déroules avec succès.
Mais c'est la que ca se corse... sur notre version de Unix (FreeBSD 7.1 et g++ 3.4.2, pour info nous ne pouvons pas changer de version de g++) il y a un SegFault au moment d'un dynamic_cast<T>(x).
back = dynamic_cast<X>(actual->methode(*autre));
// Renvois un objet bien Type en X (Sachant X est une interface et que le type de actual hérite de cette même interface)
// mais qui pointe sur NULL
// Et au moins sur Windows ca marche...
if (back != NULL)
{
...
}
else
{
...
}
Apres de multiples recherches, j'ai trouvé des infos sur un fameux RTTI (Run-Time Type Information, CFLAGS += -fno-rtti) à activer sur g++ mais sans succès.
Si vous avez des infos je suis preneur !
Merci d'avance
---------------
Benchmarks du peuple - Crysis War - Vide grenier ! - nVIDIA Tegra