Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1398 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Registration automatique d'objets globaux

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Registration automatique d'objets globaux

n°1591089
leander
Posté le 24-07-2007 à 21:52:28  profilanswer
 

Bonjour,
Je ne poste pas souvent ici, mais là je me suis désespérer et je me suis qu'un gourou du forum pourrait peut être m'aider.
Je développe un framework ou les classes se registre toute seule dans une factory. Pour faire ceci j'utilise des variables globales qui sont le code de registration dans le constructeur.
J'ai reproduit le principe dans un petit exemple recopier ci-dessous.
 
Tout ceci marche très bien si tout se trouve dans un seul projet (.exe).
Hors actuellement je suis en train de faire des librairies pour le kernel et là ça ne marche plus.
Le compilateur (Visual studio 2005) supprime les variables globales de la librairie car elles ne sont pas utilisées dans le main (ce qui est normal). Et je voudrais donc trouver un truc pour "grugger" le compilateur.
Je pensais avoir trouver en incrémentant une variable globale utiliser par le main(). Mais il se trouve que Visual à un comportement bizarre dans ce cas.
En effet, dans l'exemple ci-dessous, uniquement les 3 variables globales présent dans le fichier MyLib.cpp sont "registrées". Car le compteur est défini dans le fichier. Dans MyLib2.cpp Visual supprimer mes 2 variables globales...
 
Ceux qui veulent essayer de compiler le tout, il faut mettre MyLib.cpp et MyLib2.cpp dans un librairie statique. Et Exe.cpp dans un application console où l'on inclue la librairie statique.
 

Code :
  1. //----------------------------------------------------------------------------------------------------------------------
  2. //! \file  MyLib.h
  3. //----------------------------------------------------------------------------------------------------------------------
  4. extern int g_iCount;
  5. class keCAutoRegister
  6. {
  7. public:
  8. keCAutoRegister(int a_iCount)
  9. {
  10.  printf("%d\n", a_iCount);
  11.  ++g_iCount;
  12. }
  13. };
  14. #define keRegisterObject(x_Object, x_Value) keCAutoRegister x_Object(x_Value);


Code :
  1. //----------------------------------------------------------------------------------------------------------------------
  2. //! \file  MyLib.cpp
  3. //----------------------------------------------------------------------------------------------------------------------
  4. #include <stdio.h>
  5. #include "MyLib.h"
  6. int g_iCount = 0;
  7. keRegisterObject(g_oGlobalInstance1, 6);
  8. keRegisterObject(g_oGlobalInstance2, 2);
  9. keRegisterObject(g_oGlobalInstance3, 20);


Code :
  1. //----------------------------------------------------------------------------------------------------------------------
  2. //! \file  MyLib2.cpp
  3. //----------------------------------------------------------------------------------------------------------------------
  4. #include <stdio.h>
  5. #include "MyLib.h"
  6. keRegisterObject(g_oGlobalInstance9, 5);
  7. keRegisterObject(g_oGlobalInstance8, 0);


Code :
  1. //----------------------------------------------------------------------------------------------------------------------
  2. //! \file  Exe.cpp
  3. //----------------------------------------------------------------------------------------------------------------------
  4. #include <stdio.h>
  5. #include "MyLib.h"
  6. extern int g_iCount;
  7. int main()
  8. {
  9. printf("Nb: %d\n", g_iCount);
  10. return 0;
  11. }


 
Lorsque l'on exécute le code on obtient :

6
2
20
Nb: 3


 
Si je passe "int g_iCount = 0;" de MyLib.cpp à MyLib2.cpp, on obtient ceci :

5
0
Nb: 2


 
Et moi, je souhaiterais avoir (peu importe l'ordre de déclaration) :

6
2
20
5
0
Nb: 5


 
Merci à ceux qui m'ont lu. J'attends vos conseils avisés.
Pour informations ce code marche très bien sous Codewarrior. Sous gcc, je vais le tester dès ce soir.
Je suis donc à la recherche de solution "Microsoft specific". Via les __declspec() et cie.


Message édité par leander le 24-07-2007 à 22:58:00
mood
Publicité
Posté le 24-07-2007 à 21:52:28  profilanswer
 

n°1591091
Joel F
Real men use unique_ptr
Posté le 24-07-2007 à 21:55:27  profilanswer
 

Faudrais voir à utiliser un singleton qui géres tout ça de manière centralisé en créant des instances dynamiques de tes variables globales.

n°1591092
leander
Posté le 24-07-2007 à 22:05:21  profilanswer
 

Je ne suis pas sur que ça résoudre mon problème. Mon idée est que je rajouter un fichier avec une classe avec une macro de registration dans le .cpp, et lorsque je lance l'exe, la classe soit automatiquement registrée dans ma factory. Sans avoir à modifier aucun autre fichier.
 
Sinon, j'ai fais un test sous, gcc est j'ai le même comportement que sous Visual Studio.
C'est triste à dire, mais vive Codewarrior...

n°1591100
jojoleping​ouin
Posté le 24-07-2007 à 22:27:42  profilanswer
 

conseil de qualitay:
 
MyLib.h:
extern int g_iCount1;
extern int g_iCount2;
 
MyLib1.cpp
int g_iCount1 = 0;
register...
 
MyLib2.cpp
int g_iCount2 = 0;
register...
 
Ca te bouffe un int en mémoire mais pense a tout le temps que tu auras économisé.
Non ne me remercie pas :)

n°1591102
leander
Posté le 24-07-2007 à 22:33:13  profilanswer
 

jojolepingouin, c'est pas vraiment ça que je recherche comme solution. Ma classe de registration est unique (elle ne peut donc accéder qu'a un int) et elle sera utilisé par tous les cpp (plusieurs dizaines voir centaines).
 
Et ça veut dire que je dois faire un extern dans le main par .cpp. Ce qui est exactement le contraire de ce que je recherche.

n°1591103
jojoleping​ouin
Posté le 24-07-2007 à 22:53:42  profilanswer
 

n'empeche, ton code (sans rien toucher) chez moi ca marche :)
 
rene@moumachine ~/eclipse/code $ ./main  
5
0
6
2
20
Nb: 5
 
du coup je vais pas pouvoir t'aider plus que ca....
 
edit: si j'ai du virer ca du main :extern int g_iCount; sinon ca compilait pas.


Message édité par jojolepingouin le 24-07-2007 à 22:54:51
n°1591104
IrmatDen
Posté le 24-07-2007 à 22:54:32  profilanswer
 

Salut,
 
Tout d'abord, vire ces variables globales, c'est pas beau du tout ;)
Ensuite, fait comme te l'a dit Joel F, utilise un singleton. Ainsi, tes objets pourront simplement appeller un code du style:

Code :
  1. MaFactory::getInstance().register(this, TonIdentifiantDobjet);


 
Enfin, mauvaise cat', le C, c'est à côté (oui, y'a un 'class' et un 'public', mais c'est les 2 seules chose C++ ici).
 
Ah, et dernier point, évites de mettre le copyright de ta boîte, ça fait mauvais genre :/

n°1591106
leander
Posté le 24-07-2007 à 23:02:27  profilanswer
 

En effet, pour le copyright, j'avais pas vu, merci. Mais j'ai rien à cacher, mais c'est vrai qu'il vaut mieux éviter ;)
 
Sinon, pour ta solution ca marche en effet, mais c'est pas le but rechercher. La registration comme tu la proposes, elle doit se faire dans le main ou une fonction appeler par le main.
Hors je souhaite que la registration se fasse automatique lorsqu'un .cpp se trouve dans un projet. Ca peut paraitre non courant, mais c'est super pratique et j'utilise cette méthode depuis plus de 5 ans.
 
Les seules solutions qui me conviendront seront celle ou les registrations se feront comme ceci dans un .cpp:

Code :
  1. keRegisterObject(g_oGlobalInstance9, 5);


 
La solution doit donc venir d'une modification dans la macro keRegisterObject() ou la classe keCAutoRegister et son constructeur.
Jusqu'a présent j'avais une solution spécifique pour Codewarrior et sous windows je ne faisais pas de librairie.
Mais j'aimerais vraiment pouvoir faire des librairies et c'est pour cela que je cherche un solution spéficique windows (et gcc aussi remarque...) ou générique.


Message édité par leander le 24-07-2007 à 23:04:26
n°1591124
SquiZZ
Posté le 25-07-2007 à 00:46:03  profilanswer
 

J'ai fait un truc approchant il y a qques temps si je me rappelle bien.
tu peux essayer avec un truc genre créer une fonction d'enregistrement qui retourne un bool et dans tes cpp faire :

Code :
  1. namespace { const bool foo = RegisterFunc(pouet, 9); }


avec un petit define pour enrober le tout ça devrait le faire.
Je faisais ça sous VC6 pour une factory et ça marchait.
[edit] avec un singleton c'est encore mieux quand même.


Message édité par SquiZZ le 25-07-2007 à 00:47:17
n°1591158
leander
Posté le 25-07-2007 à 09:31:50  profilanswer
 

SquiZZ, en fait, le principe est à peu pres le meme que celui que le propose. Ca marche très bien si les fichiers sont tous au sein d'un projet executable.
Mais dès que l'on met ceci dans une library, le probleme est le meme. Le code est supprimé.
 
Mais merci pour ta réponse, ca va dans le sens de ce que je recherche.
 
Pour le singleton, j'en ai un pour ma factory bien sur. Mais pour la registration, je prefere une registration automatique plutot qu'une manuelle appelé d'une façon ou d'une autre via le main. C'est beaucoup plus souble pour le développement en équipe et en multiplateforme.

mood
Publicité
Posté le 25-07-2007 à 09:31:50  profilanswer
 

n°1591285
KangOl
Profil : pointeur
Posté le 25-07-2007 à 13:11:55  profilanswer
 

mais elle est pas automatique puisque tu appelles ta macro (que tu peux récrire pour faire appel a un singleton)

n°1591298
leander
Posté le 25-07-2007 à 13:57:26  profilanswer
 

Ma macro est écrit dans un cpp en dehors de toutes fonctions. Si tu arrives à faire la même chose avec un singleton, je suis preneur.
 
D'ailleurs, dans mon framework, mon code de base appelle un singleton (dans le constructeur de keCAutoRegister). Le problème n'est pas comment faire l'appel (via un singleton ou une fct C, etc.), mais que du code, mis dans un .cpp soit exécuté au lancement de l'application sans que j'ai à faire de référence sur ce code depuis d'autre cpp. Et ceci, lorsque le code se trouve dans un .lib (car dans un executable ça marche déjà).

n°1591359
SquiZZ
Posté le 25-07-2007 à 15:50:56  profilanswer
 

Le problème c'est donc que le programme n'utilise pas de code présent dans les librairies statiques donc elles ne sont pas incluses pendant le linkage.
A part mettre une fonction InitLibTotoxxx dans chaque lib et l'appeler depuis le main je vois pas de solution.

n°1591465
leander
Posté le 25-07-2007 à 19:29:05  profilanswer
 

SquiZZ, c'est en effet exactement ça mon problème.

n°1591573
++fab
victime du syndrome IH
Posté le 25-07-2007 à 23:36:55  profilanswer
 

leander a écrit :

C'est beaucoup plus souble pour le développement en équipe et en multiplateforme.


En multiplateforme ? la preuve dans ce fil.
 
Cette technique peut éventuellement fonctionner en créant un DSO au lieu d'une bibliothèque statique.

n°1591626
leander
Posté le 26-07-2007 à 09:03:15  profilanswer
 

C'est quoi un DSO ?
 
Pour le multiplateforme, s'il y a une solution générique tant mieux. Sinon, il y a toujours la solution de ne pas utiliser de librarie.

n°1591862
IrmatDen
Posté le 26-07-2007 à 14:47:57  profilanswer
 

C'est une bibliothèque partagé (comme un .dll/win, .so/unixoide ou .dynlib pour osx je crois), mais google t'en dira plus que moi.
J'utilise assez régulièrement cette méthode, je scanne avec la factory les "plugins" pour voir si je peux obtenir un objet du type attendu; si c'est le cas, je l'enregistre, sinon, j'ignore la bibliothèque. Je ne sais pas si c'est à ça que ++fab pensait, mais je ne connais pas vraiment d'autres façons en fait :)

n°1592414
jojoleping​ouin
Posté le 27-07-2007 à 14:49:47  profilanswer
 

et avec un static ca marche pas ?

Code :
  1. #define keRegisterObject(x_Object, x_Value) static keCAutoRegister x_Object(x_Value);

n°1598642
leander
Posté le 11-08-2007 à 18:51:11  profilanswer
 

non une static ne marche pas.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Registration automatique d'objets globaux

 

Sujets relatifs
[VBA-Access] Fermeture automatique (inactivité)gallerie photo avec MAJ automatique
Redirection automatique vers waprafraichissement automatique affichage
Afficher deux objets héritant de QFrame dans un QMainWindowsinsertion de données automatique
objets métiers -> base de donnéesprograme insertion annonce automatique
[ WaitForMultipleObjects ] Lister tous les objets signales ?Vista : création automatique d'un dossier compressé
Plus de sujets relatifs à : Registration automatique d'objets globaux


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR