2.1.2 Le main du programme

Enfin, je dis ça, mais il n'y aura que le main, car notre programme va être très petit.

Pour ce programme, nous n'allons pas passer de paramètre.

Nous aurons besoin :

  • D'un nombre de valeur à générer
  • D'une valeur de départ pour x
  • D'une valeur final pour x

Dans le même dossier que plugin.c et plugin.so on écrit le fichier main.cpp :

On commence par les includes et notre fameuse macro :

1
2
3
4
5
6
7
#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);

Ensuite, on définit le type de la fonction f(x), cela permettra de la passer en paramètre à la fonction qui fera l'affichage :

1
typedef double(*FunctYdeX)(double);

La fonction qui va afficher les valeurs de f(x) dans la console :

1
2
3
4
5
6
7
8
9
10
11
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;
	}
}

Et la fonction main qui n'a presque changer depuis tout à l'heure :

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
int main(int argc, char **argv) {
	double xmin(-10.0);
	double xmax(10.0);
	size_t nbValues(100);
	
	cout << "f(x) drawer" << endl;
	//la variable qui nous permettra de tenir la lib m
	void *handle;
	//la futur fonction cos 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.so", 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);
}

Ce qui donne au final :

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

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

int main(int argc, char **argv) {
	double xmin(-10.0);
	double xmax(10.0);
	size_t nbValues(100);
	
	cout << "f(x) drawer" << endl;
	//la variable qui nous permettra de tenir la lib m
	void *handle;
	//la futur fonction cos 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.so", 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

Maintenant nous allons le compiler avec G++ :

g++ -Wall main.cpp -ldl -o test

Notez que je n'ai pas mis -lm pour compiler le main.cpp car il n'y a pas d'appel de fonction à la libm dans ce programme.

Testons si le programme à bien été créer :

ls
main.cpp  plugin.c  plugin.so  test