C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[UNIX] ar et g++

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Mungo Deepdelver[CEA][Lap
Guest





PostPosted: Wed Mar 30, 2005 8:20 am    Post subject: [UNIX] ar et g++ Reply with quote




Bonjour,
je debute et je rencontre quelques problèmes.

Soit le code suivant :

int main(int ac,char **av)
{
MPI::Init();
.....
MPI::Finalize();
}

Je dois imperativement faire MPI::Init() au debut
et MPI::Finalize() a la fin du main.

Je veux encapsuler la lib MPI dans qqchose de plus haut niveaux
et en particuler je souhaiterais m'affranchir de ces deux appels
explicites.

Voici un exemple pour illustrer la methode que j'emploie actuellement :
Dans main.cc :
<CODE>
#include <cstdlib>

int main(int ac,char **av)
{
return EXIT_SUCCESS;
}
</CODE>

dans starter.h

<CODE>
#ifndef Starter_H_
#define Starter_H_

class Starter
{
private:
static Starter instance_;
Starter();
public:
~Starter();
};// class Starter

#endif// #ifndef TOTO_H_
</CODE>

dans starter.cc

<CODE>
#include "starter.h"
#include <iostream>

using namespace std;

Starter Starter::instance_;

Starter::Starter()
{
cout << '[' << __FUNCTION__ << ']' << "Init" << endl;
}

Starter::~Starter()
{
cout << '[' << __FUNCTION__ << ']' << "Finalize" << endl;
}

ensuite,
<SHELL>
g++ -c starter.cc
g++ main.cc starter.o
./a.out
[Starter]Init
[Starter]Finalize
</SHELL>

tout vas bien, le constructeur et le destructeur de l'instance static
instance_ de type starter sont appelés.

Par contre si je procéde comme ça:
<SHELL>
g++ -c starter.cc
ar -q libstarter.a starter.o
g++ main.cc -L. -lstarter // ou aussi bien g++ main.cc libstarter.a
./a.out
//rien
</SHELL>

apparement l'instance instance_ n'est pas construite
(encore moin détruite).

Ma question :
pourquoi la deuxième façon de faire ne fonctionne pas.

Remarque :
je pense que cette methode n'est pas terrible dans la mesure ou l'on
a aucun moyen de controler l'ordre dans lequel sont construites les
données static, ce qui pourrait poser problème si d'autres données
static faisaient dépendaient de la construction d'instance_.
Quelqu'un a-t-il une autre methode ?
Une "lazy initialisation" de l'objet instance_ pourrait resoudre ce
problème je pense.

J'espère que ma question est bien posée.

Bien à vous,
Sébastien
--

int main(){int j=1234,putchar();char t[]=":@abcdefghij-lmnopqrstuv"
"wxyz.n",*i="@jq:.pn.q:ibf.gdnoz.dn@ewnlwh-i",*strchr();while(*i)
{j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);}return 0;}
Back to top
Gilles Civario
Guest





PostPosted: Wed Mar 30, 2005 9:08 am    Post subject: Re: [UNIX] ar et g++ Reply with quote



Mungo Deepdelver[CEA][Lapin Or is back] wrote:
Quote:
Bonjour,
je debute et je rencontre quelques problèmes.

Soit le code suivant :

int main(int ac,char **av)
{
MPI::Init();
.....
MPI::Finalize();
}

Je dois imperativement faire MPI::Init() au debut
et MPI::Finalize() a la fin du main.

Je veux encapsuler la lib MPI dans qqchose de plus haut niveaux
et en particuler je souhaiterais m'affranchir de ces deux appels
explicites.

Voici un exemple pour illustrer la methode que j'emploie actuellement :
Dans main.cc :
CODE
#include
int main(int ac,char **av)
{
return EXIT_SUCCESS;
}
/CODE

dans starter.h

CODE
#ifndef Starter_H_
#define Starter_H_

class Starter
{
private:
static Starter instance_;
Starter();
public:
~Starter();
};// class Starter

#endif// #ifndef TOTO_H_
/CODE

dans starter.cc

CODE
#include "starter.h"
#include
using namespace std;

Starter Starter::instance_;

Starter::Starter()
{
cout << '[' << __FUNCTION__ << ']' << "Init" << endl;
}

Starter::~Starter()
{
cout << '[' << __FUNCTION__ << ']' << "Finalize" << endl;
}
/CODE

ensuite,
SHELL
g++ -c starter.cc
g++ main.cc starter.o

Ici, tu force au link l'inclusion de ton fichier objet starter.o

Quote:
./a.out
[Starter]Init
[Starter]Finalize
/SHELL

tout vas bien, le constructeur et le destructeur de l'instance static
instance_ de type starter sont appelés.

Par contre si je procéde comme ça:
SHELL
g++ -c starter.cc
ar -q libstarter.a starter.o
g++ main.cc -L. -lstarter // ou aussi bien g++ main.cc libstarter.a

Ici, tu rend disponible les objets contenus dans ta bibliothèque libstarter.a.
Le linker va regarder séquentiellemnt dans la liste des bibliothèques mentionnées
pour y trouver les éventuels symboles non résolus. Or, comme main ne fait pas
référence à un symbole définit dans starter.o, starter.o ne sera pas inclus par
le linker.

Une solution serait peut être d'en faire une bibliothèque dynamique libstarter.so et
de positionner LD_PRELOAD à libstarter.so.

Gilles.

Back to top
Mungo Deepdelver[CEA][Lap
Guest





PostPosted: Wed Mar 30, 2005 10:18 am    Post subject: Re: [UNIX] ar et g++ Reply with quote



On Wed, 30 Mar 2005, Gilles Civario wrote:

Quote:
SHELL
g++ -c starter.cc
g++ main.cc starter.o

Ici, tu force au link l'inclusion de ton fichier objet starter.o

./a.out
[Starter]Init
[Starter]Finalize
/SHELL

tout vas bien, le constructeur et le destructeur de l'instance static
instance_ de type starter sont appelés.

Par contre si je procéde comme ça:
SHELL
g++ -c starter.cc
ar -q libstarter.a starter.o
g++ main.cc -L. -lstarter // ou aussi bien g++ main.cc libstarter.a

Ici, tu rend disponible les objets contenus dans ta bibliothèque libstarter.a.
Le linker va regarder séquentiellemnt dans la liste des bibliothèquesmentionnées
pour y trouver les éventuels symboles non résolus. Or, comme main ne fait pas
référence à un symbole définit dans starter.o, starter.o ne sera pas inclus par
le linker.

Une solution serait peut être d'en faire une bibliothèque dynamique libstarter.so et
de positionner LD_PRELOAD à libstarter.so.


Merci,
je n'avais pas conscience de cette subtilité.

Quote:
Gilles.


--

int main(){int j=1234,putchar();char t[]=":@abcdefghij-lmnopqrstuv"
"wxyz.n",*i="@jq:.pn.q:ibf.gdnoz.dn@ewnlwh-i",*strchr();while(*i)
{j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);}return 0;}

Back to top
Christophe de VIENNE
Guest





PostPosted: Wed Mar 30, 2005 10:28 am    Post subject: Re: [UNIX] ar et g++ Reply with quote

Gilles Civario wrote:
Quote:
Or, comme main ne
fait pas
référence à un symbole définit dans starter.o, starter.o ne sera pas
inclus par
le linker.

Une solution serait peut être d'en faire une bibliothèque dynamique
libstarter.so et
de positionner LD_PRELOAD à libstarter.so.

Une autre méthode est d'utiliser l'option -u de gcc en lui donnant un
symbole défini dans starter.o

A+

Christophe


--
Christophe de Vienne

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Mar 30, 2005 4:06 pm    Post subject: Re: ar et g++ Reply with quote

Gilles Civario wrote:
Quote:
Mungo Deepdelver[CEA][Lapin Or is back] wrote:

[...]

Quote:
Ici, tu rend disponible les objets contenus dans ta
bibliothèque libstarter.a. Le linker va regarder
séquentiellemnt dans la liste des bibliothèques mentionnées
pour y trouver les éventuels symboles non résolus.

Pas forcément séquenciellement. Tout dépend du système (et je me
suis bien servi des systèmes où il regardait séquentiellement),
mais actuellement, le plupart des systèmes traitent des
bibliothèques comme des bases à accès aléatoire. Certains même,
comme Windows (mais non Unix) font l'amalgame de toutes les
bibliothèques ; l'ordre ne joue que quand le même symbole se
trouve défini dans plusieurs bibliothèques.

Quote:
Or, comme
main ne fait pas référence à un symbole définit dans
starter.o, starter.o ne sera pas inclus par le linker.

Une solution serait peut être d'en faire une bibliothèque
dynamique libstarter.so et de positionner LD_PRELOAD à
libstarter.so.

C'est penible.

Personellement, je ne suis pas tout à fait convaincu de sa
solution dans ce cas-ci. J'aurais tendance à vouloir un objet
explicit en main. Mais peut-être je connais pas bien le
problème ; je ne sais pas trop à quoi sert ces appels.

Aussi, je suppose que dans la pratique, ces appels doivent bien
initialiser quelque chose dont il se sert. Dans ce cas-là, une
solution serait d'encapsuler cette chose dans une classe --
peut-être un singleton, mais pas forcement. Du coup, si
quelqu'un s'en sert, l'éditeur de liens incorpore la classe dans
le programme, et sinon, non. Il a les appels dans les programmes
qui en ont besoin, et non dans les autres programmes.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.