2.2.6 Le nouveau fichier main.cpp

Voici le nouveau fichier main.cpp :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <iostream>
#include <math.h>

#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;

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;
	}
}

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 <math.h>\n\ndouble callingFunctionPlugin(double x){\n\treturn %s;\n}\n\n", calcExpr.c_str());
	fclose(fp);
	return true;
}

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;
	}
}

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);
}

Le fichier main.cpp.