[...]
[...]
[...]
[...]
[...]
[...]
Delf wrote:[...]
[22:08][ src]# make libs
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
plugins/Test.cpp: In function `Plugins* Create()':
plugins/Test.cpp:72: error: cannot allocate an object of type `CTest'
plugins/Test.cpp:72: error: because the following virtual functions
are abstract:
plugins/../Plugins.h:74: error: virtual Plugins::LaunchStatus
Plugins::Launch(const std::string&) const
*** Error code 1
Delf wrote:
[...]
[22:08][delf@freaker src]# make libs
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
plugins/Test.cpp: In function `Plugins* Create()':
plugins/Test.cpp:72: error: cannot allocate an object of type `CTest'
plugins/Test.cpp:72: error: because the following virtual functions
are abstract:
plugins/../Plugins.h:74: error: virtual Plugins::LaunchStatus
Plugins::Launch(const std::string&) const
*** Error code 1
Delf wrote:[...]
[22:08][ src]# make libs
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
plugins/Test.cpp: In function `Plugins* Create()':
plugins/Test.cpp:72: error: cannot allocate an object of type `CTest'
plugins/Test.cpp:72: error: because the following virtual functions
are abstract:
plugins/../Plugins.h:74: error: virtual Plugins::LaunchStatus
Plugins::Launch(const std::string&) const
*** Error code 1
où "string" n'est pas "string&".
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C servant
de factory - un extern "C" Plugins* getInstance() - la libération de
cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
où "string" n'est pas "string&".
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C servant
de factory - un extern "C" Plugins* getInstance() - la libération de
cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
où "string" n'est pas "string&".
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C servant
de factory - un extern "C" Plugins* getInstance() - la libération de
cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
Je compile la librairie test.so :
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
Je compile la librairie test.so :
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
Je compile la librairie test.so :
g++ -shared -fPIC plugins/Test.cpp -o plugins/test.so -I
/usr/local/include/libxml2/ -I /usr/local/include/
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C
servant de factory - un extern "C" Plugins* getInstance() - la
libération de cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
Je n'ai pas saisi.
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C
servant de factory - un extern "C" Plugins* getInstance() - la
libération de cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
Je n'ai pas saisi.
sur le modèle lui-même, mille (ou presque) écritures sont possibles,
mais il peut être élégant de n'exporter qu'une seule statique C
servant de factory - un extern "C" Plugins* getInstance() - la
libération de cette instance pouvant se faire par une méthode d'instance
(par ex: void Plugin::release() { delete this; } ).
Je n'ai pas saisi.
ceci permettra à l'appli de libérer un plug-in par plugin->release() au
lieu de récupérer l'adresse de la fct C statique Destroy et de l'appeler
- tu devras déjà conserver un tableau de fonction des factories
("Create" dans ton exemple, "getInstance" dans mon propos), il est peut
être intéressant de ne pas avoir en plus un tableau de Destroy'ers.
la méthode "IsRightPlugins" est également byzarre
ceci permettra à l'appli de libérer un plug-in par plugin->release() au
lieu de récupérer l'adresse de la fct C statique Destroy et de l'appeler
- tu devras déjà conserver un tableau de fonction des factories
("Create" dans ton exemple, "getInstance" dans mon propos), il est peut
être intéressant de ne pas avoir en plus un tableau de Destroy'ers.
la méthode "IsRightPlugins" est également byzarre
ceci permettra à l'appli de libérer un plug-in par plugin->release() au
lieu de récupérer l'adresse de la fct C statique Destroy et de l'appeler
- tu devras déjà conserver un tableau de fonction des factories
("Create" dans ton exemple, "getInstance" dans mon propos), il est peut
être intéressant de ne pas avoir en plus un tableau de Destroy'ers.
la méthode "IsRightPlugins" est également byzarre
Mon application doit charger à l'exécution un ensemble inconnu de
plugins situés dans un répertoire donné.
Ces plugins sont aussi écrits en C++ et implémentent une interface
IPlugins.
Je compile les librairies en utilisant la commande suivante :
g++ -shared -I /usr/local/include/libxml2/ -I /usr/local/include/
fichier.cpp -o fichier.so
Ma question, comment récupérer dans le répertoire donné tous
les .so, s'assurer qu'il s'agit bien de plugins (on peut avoir
un fichier texte nommé xxx.so), charger chaque plugins et
lancer les méthodes ?
Ca fait beaucoup de questions...
J'ai pu voir dlopen() et extern "C" (mais pour les librairies en C...).
Pour dlopen(), j'utilise le code suivant :
void* handle = dlopen("./plugins/test.so", RTLD_LAZY);
if (handle == NULL)
{
std::cout << dlerror() << std::endl;
exit(1);
}
En sortie : ./plugins/test.so: Undefined symbol "_ZN8IPluginsC2Ev"
Par ailleurs, on m'a dit que dlopen() ne servait pas dans mon
cas...
Mon application doit charger à l'exécution un ensemble inconnu de
plugins situés dans un répertoire donné.
Ces plugins sont aussi écrits en C++ et implémentent une interface
IPlugins.
Je compile les librairies en utilisant la commande suivante :
g++ -shared -I /usr/local/include/libxml2/ -I /usr/local/include/
fichier.cpp -o fichier.so
Ma question, comment récupérer dans le répertoire donné tous
les .so, s'assurer qu'il s'agit bien de plugins (on peut avoir
un fichier texte nommé xxx.so), charger chaque plugins et
lancer les méthodes ?
Ca fait beaucoup de questions...
J'ai pu voir dlopen() et extern "C" (mais pour les librairies en C...).
Pour dlopen(), j'utilise le code suivant :
void* handle = dlopen("./plugins/test.so", RTLD_LAZY);
if (handle == NULL)
{
std::cout << dlerror() << std::endl;
exit(1);
}
En sortie : ./plugins/test.so: Undefined symbol "_ZN8IPluginsC2Ev"
Par ailleurs, on m'a dit que dlopen() ne servait pas dans mon
cas...
Mon application doit charger à l'exécution un ensemble inconnu de
plugins situés dans un répertoire donné.
Ces plugins sont aussi écrits en C++ et implémentent une interface
IPlugins.
Je compile les librairies en utilisant la commande suivante :
g++ -shared -I /usr/local/include/libxml2/ -I /usr/local/include/
fichier.cpp -o fichier.so
Ma question, comment récupérer dans le répertoire donné tous
les .so, s'assurer qu'il s'agit bien de plugins (on peut avoir
un fichier texte nommé xxx.so), charger chaque plugins et
lancer les méthodes ?
Ca fait beaucoup de questions...
J'ai pu voir dlopen() et extern "C" (mais pour les librairies en C...).
Pour dlopen(), j'utilise le code suivant :
void* handle = dlopen("./plugins/test.so", RTLD_LAZY);
if (handle == NULL)
{
std::cout << dlerror() << std::endl;
exit(1);
}
En sortie : ./plugins/test.so: Undefined symbol "_ZN8IPluginsC2Ev"
Par ailleurs, on m'a dit que dlopen() ne servait pas dans mon
cas...
je ne connais même pas de
solution portable : les fonctions s'appelle dlopen, dlsym et
dlclose sous Unix.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
je ne connais même pas de
solution portable : les fonctions s'appelle dlopen, dlsym et
dlclose sous Unix.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
je ne connais même pas de
solution portable : les fonctions s'appelle dlopen, dlsym et
dlclose sous Unix.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
James Kanze wrote:
je ne connais même pas de solution portable : les fonctions
s'appelle dlopen, dlsym et dlclose sous Unix.
Je ne cherche pas à faire une application portable, qu'elle
fonctionne sous Linux et UNiX, ça ne sera déjà pas mal :)
Pour l'histoire du répertoire, j'ai utilisé la panoplie opendir,
readdir, etc.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
Ne connaissant pas le sujet sous UNiX (je viens du monde
dotNET), je suis parti sur ce HowTo :
http://www.faqs.org/docs/Linux-mini/C++-dlopen.html
Pour l'instant, mon PluginsManager basé sur ce document
fonctionne sous FreeBSD. Je testerai par la suite sous
d'autres systèmes Linux/UNiX.
James Kanze wrote:
je ne connais même pas de solution portable : les fonctions
s'appelle dlopen, dlsym et dlclose sous Unix.
Je ne cherche pas à faire une application portable, qu'elle
fonctionne sous Linux et UNiX, ça ne sera déjà pas mal :)
Pour l'histoire du répertoire, j'ai utilisé la panoplie opendir,
readdir, etc.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
Ne connaissant pas le sujet sous UNiX (je viens du monde
dotNET), je suis parti sur ce HowTo :
http://www.faqs.org/docs/Linux-mini/C++-dlopen.html
Pour l'instant, mon PluginsManager basé sur ce document
fonctionne sous FreeBSD. Je testerai par la suite sous
d'autres systèmes Linux/UNiX.
James Kanze wrote:
je ne connais même pas de solution portable : les fonctions
s'appelle dlopen, dlsym et dlclose sous Unix.
Je ne cherche pas à faire une application portable, qu'elle
fonctionne sous Linux et UNiX, ça ne sera déjà pas mal :)
Pour l'histoire du répertoire, j'ai utilisé la panoplie opendir,
readdir, etc.
-- Sous Unix, dlsym ne rend qu'un void*, et il n'y a pas de
conversion standard void* vers pointeur vers fonction.
Certains compilateurs le supportent avec reinterpret_cast
(ou un cast à la C), comme extension, mais selon l'Open
Group, la solution préconcisée (jusqu'à ce que l'interface
soit corrigée, ce qui est prévu, mais sans qu'ils disent
quand), c'est quelque chose du genre :
[...]
Ne connaissant pas le sujet sous UNiX (je viens du monde
dotNET), je suis parti sur ce HowTo :
http://www.faqs.org/docs/Linux-mini/C++-dlopen.html
Pour l'instant, mon PluginsManager basé sur ce document
fonctionne sous FreeBSD. Je testerai par la suite sous
d'autres systèmes Linux/UNiX.