Comment procéder pour charger du code C compilé au moment de l'exécution, puis appeler des fonctions en son sein? Pas comme simplement appeler exec ().
EDIT: Le programme qui charge le module est en C.
Comment procéder pour charger du code C compilé au moment de l'exécution, puis appeler des fonctions en son sein? Pas comme simplement appeler exec ().
EDIT: Le programme qui charge le module est en C.
dlopen est le chemin à parcourir. Voici quelques exemples:
Chargement d'un plugin avec dlopen:
#include <dlfcn.h>
...
int
main (const int argc, const char *argv[])
{
char *plugin_name;
char file_name[80];
void *plugin;
...
plugin = dlopen (file_name, RTLD_NOW);
if (!plugin)
{
fatal ("Cannot load %s: %s", plugin_name, dlerror ());
}
La compilation ci-dessus:
% cc -ldl -o program program.o
Ensuite, en supposant que cette API pour les plugins:
/* The functions we will find in the plugin */
typedef void (*init_f) ();
init_f init;
typedef int (*query_f) ();
query_f query;
Trouver l'adresse de la fonction init() dans le plugin:
init = dlsym (plugin, "init");
result = dlerror ();
if (result)
{
fatal ("Cannot find init in %s: %s", plugin_name, result);
}
init ();
Avec l'autre fonction query(), qui retourne une valeur:
query = dlsym (plugin, "query");
result = dlerror ();
if (result)
{
fatal ("Cannot find query in %s: %s", plugin_name, result);
}
printf ("Result of plugin %s is %d\n", plugin_name, query ());
Vous pouvez récupérer l'exemple complet en ligne.
Le voir, cette question a été répondu, mais la pensée d'autres personnes intéressées par le sujet peuvent apprécier une plate-forme de l'exemple d'un vieux plugin en fonction de l'application. L'exemple fonctionne sur win32 et linux, et seaches et appelle une fonction appelée 'constructeur' dans l'chargé dynamiquement .donc ou .dll spécifiée dans le fichier argument. L'exemple est en c++, mais la procédure devrait être la même pour les c de.
//firstly the includes
#if !defined WIN32
#include <dlfcn.h>
#include <sys/types.h>
#else
#include <windows.h>
#endif
//define the plugin's constructor function type named PConst
typedef tcnplugin* (*PConst)(tcnplugin*,tcnplugin*,HANDLE);
//loads a single specified tcnplugin,allmychildren[0] = null plugin
int tcnplugin::loadplugin(char *file) {
tcnplugin *hpi;
#if defined WIN32 //Load library windows style
HINSTANCE hplugin=LoadLibrary(file);
if (hplugin != NULL) {
PConst pinconstruct = (PConst)GetProcAddress(hplugin,"construct");
#else //Load it nix style
void * hplugin=dlopen(file,RTLD_NOW);
if (hplugin != NULL) {
PConst pinconstruct = (PConst)dlsym(hplugin,"construct");
#endif
if (pinconstruct != NULL) { //Try to call constructor function in dynamically loaded file, which returns a pointer to an instance of the plugin's class
hpi = pinconstruct(this, this, hstdout);
} else {
piprintf("Cannot find constructor export in plugin!\n");
return 0;
}
} else {
piprintf("Cannot open plugin!\n");
#if !defined WIN32
perror(dlerror());
#endif
return 0;
}
return addchild(hpi); //add pointer to plugin's class to our list of plugins
}
Pourrait aussi être mentionné que si le module qui est des fonctions que vous souhaitez appeler, est écrit en c++, il faut déclarer la fonction avec extern "C", tels que:
extern "C" pcparport * construct(tcnplugin *tcnptr,tcnplugin *parent) {
return new pcparport(tcnptr,parent,"PCPARPORT",0,1);
}
Si vous êtes prêt à envisager le cadre, Qt fournit QPluginLoader: http://qt-project.org/doc/qt-4.8/qpluginloader.html
Si vous avez besoin de plus de précision, de contrôle, Qt fournit également un moyen de charger des bibliothèques à la volée avec QLibrary: http://qt-project.org/doc/qt-4.8/qlibrary.html
Mieux encore, ce sont portable sur l'ensemble des plates-formes.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.