#include #include #include #include #include #define MY_DLSYM(X,Y,Z) *(void **)(&X) = dlsym(Y, Z); #define PLUGIN_SOURCE "autoPlugin.c" #define PLUGIN_LIB "autoPlugin.so" typedef double(*FunctYdeX)(double); using namespace std; ///fonction qui affiche les nbValues valeurs de f(x) entre xmin et xmax /** @param functionYdeX : fonction f(x) à utiliser * @param xmin : valeur minimale de x * @param xmax : valeur maximale de x * @param nbValues : nombre de valeur de x à afficher */ void displayValues(FunctYdeX functionYdeX, double xmin, double xmax, size_t nbValues){ double x; double dx((xmax - xmin)/((double)nbValues)); for(size_t i(0); i < nbValues; ++i){ x = xmin + ((double)i)*dx; cout << "x = " << x << " => f(x) = " << functionYdeX(x) << endl; } } ///fonction qui permet d'écrire le plugin avant de le compilé /** @param fileNamePlugin : nom du fichier de sauvegarde du plugin * @param calcExpr : expression du calcul à effectuer * @return true si la fonction à réussie à créer le fichier, false sinon */ bool writePlugin(const std::string & fileNamePlugin, const std::string & calcExpr){ if(fileNamePlugin == "" || calcExpr == "") return false; FILE* fp = fopen(fileNamePlugin.c_str(), "w"); if(fp == NULL) return false; fprintf(fp, "\n#include \n\ndouble callingFunctionPlugin(double x){\n\treturn %s;\n}\n\n", calcExpr.c_str()); fclose(fp); return true; } ///fonction qui peremt de compiler le plugin /** @param pluginFileName : nom du fichier source du plugin * @param pluginSoName : nom de la lib compilée du plugin * @return true si la fonction a réussie, false sinon */ bool compilePlugin(const std::string & pluginFileName, const std::string & pluginSoName){ if(pluginFileName == "" || pluginSoName == "") return false; //on créer la commande pour compiler le plugin string cmd("gcc -fPIC -shared -O3 " + pluginFileName + " -lm -o " + pluginSoName); //on exécute cette commande if(system(cmd.c_str()) != 0){ cerr << "compilePlugin : le plugin n'a pas pu être compilé." << endl; return false; }else{ return true; } } ///fonction qui créer le plugin /** @return true si la fonction a réussie, false sinon */ bool makePlugin(){ string expression(""); cout << "Expression de la fonction f(x) : "; cin >> expression; if(expression == ""){ cerr << "makePlugin : expression vide." << endl; return false; } if(!writePlugin(PLUGIN_SOURCE, expression)){ cerr << "makePlugin : impossible d'écrire les sources du plugin." << endl; return false; } if(!compilePlugin(PLUGIN_SOURCE, PLUGIN_LIB)){ cerr << "makePlugin : impossible de compiler le plugin." << endl; return false; } return true; } int main(int argc, char **argv) { double xmin(-10.0); double xmax(10.0); size_t nbValues(100); cout << "f(x) drawer" << endl; if(!makePlugin()){ cerr << "generatednumberlibdynamic : Impossible de créer le plugin." << endl; return 1; } //la variable qui nous permettra de tenir la lib m void *handle; //la future fonction f(x) que l'on ira chercher dans lib m double (*funcFdeX)(double); //une éventuelle chaîne d'erreur si un truc ne se passe pas comme prévu char *error; handle = dlopen(PLUGIN_LIB, RTLD_LAZY); if(!handle){ fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } dlerror(); //Efface une erreur existante MY_DLSYM(funcFdeX, handle, "callingFunctionPlugin") error = dlerror(); if(error != NULL){ fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); } displayValues(funcFdeX, xmin, xmax, nbValues); cout << "Fermeture du plugin" << endl; dlclose(handle); exit(EXIT_SUCCESS); }