first working plugin demo

This commit is contained in:
tth 2021-09-16 18:31:11 +02:00
parent 3437173612
commit d20a832a8d
6 changed files with 113 additions and 4 deletions

3
.gitignore vendored
View File

@ -24,3 +24,6 @@ code/no-op
code/get-signal code/get-signal
code/fifo-tx code/fifo-tx
code/fifo-rx code/fifo-rx
code/plugiciel.so
code/appelant

View File

@ -1,9 +1,26 @@
\chapter{Plugins} \chapter{Plugins}
\index{plugin} \index{plugin}
\texttt{dlopen}\index{dlopen} % ------------------------------------
dlclose, dlopen, dlmopen - open and close a shared object Le concept de bibliothèque partagée
(\textsl{shared library} en anglais est apparu, du moins
dans le monde Unix, avec \textsl{SunOS 4}, en 1989.
Mais il est probable que ce concept existait déja dans
d'autres mondes, peut-être avec \textsl{AmigaOS} ou
\textsl{VAX/VMS}\index{VMS}\dots
Et c'est en partie sur ce concept qu'est basé le premier
mécanisme que nous allond écouvrir~:
\texttt{dlopen} et sa petite famille.
% ------------------------------------
\section{Mécanique}
\index{dlopen}
\texttt{dlclose, dlopen, dlmopen - open and close a shared object}
\begin{quote} \begin{quote}
The function dlopen() loads the dynamic shared object (shared library) The function dlopen() loads the dynamic shared object (shared library)
@ -13,9 +30,44 @@ functions in the dlopen API, such as dlsym(3), dladdr(3), dlinfo(3),
and dlclose(). and dlclose().
\end{quote} \end{quote}
% ------------------------------------
\section{Un exemple ?} \section{Un exemple ?}
XXX\index{XXX} Comme d'habitude, je vais proposer un exemple un peu artificiel,
mais qui, de part sa simplicité, illustrera clairement
les concepts de base. Partons du principe que nous avons
un tableau de quatre nombres flottants, et que nous souhaitons
proposer un affichage de ce tableau modifiable à volonté.
Nous allons donc écrire notre fonction personnelle d'affichage
dans un fichier \textsc{.c} indépendant (le plugiciel) et qui
sera chargé dynamiquement au \textsl{run-time} par le logiciel
principal (l'appelant).
\subsection{Le plugiciel}
C'est ici que nous trouverons le code actif de l'exemple,
l'utilité de notre \textsl{usecase} reste à déterminer par nos
lecteurs, à titre d'exercice.
\lstinputlisting[language=c]{code/plugiciel.c}
\subsection{L'appelant}
\lstinputlisting[language=c]{code/appelant.c}
Ah, les choses se corsent un peu, il y a un pointeur bien
tortueux à déchiffrer. Il était temps.
\texttt{void (*funcname)(const char*, const float *);}
% ------------------------------------
\section{Autres langages}

View File

@ -19,7 +19,7 @@ arguments: arguments.c Makefile
no-op: no-op.c Makefile no-op: no-op.c Makefile
gcc -Wall $< -o $@ gcc -Wall $< -o $@
#------------- IPC #------------- IPC -----------------------
get-signal: get-signal.c Makefile get-signal: get-signal.c Makefile
gcc -Wall $< -o $@ gcc -Wall $< -o $@
@ -35,3 +35,11 @@ fifo-tx: fifo-tx.c my-fifo.h dtime.o Makefile
fifo-rx: fifo-rx.c my-fifo.h dtime.o Makefile fifo-rx: fifo-rx.c my-fifo.h dtime.o Makefile
gcc -Wall $< dtime.o -o $@ gcc -Wall $< dtime.o -o $@
#------------- PLUGIN --------------------
plugiciel.so: plugiciel.c plugiciel.h Makefile
gcc -Wall -shared -fPIC $< -o $@
appelant: appelant.c plugiciel.h Makefile
gcc -Wall $< -ldl -o $@

33
code/appelant.c Normal file
View File

@ -0,0 +1,33 @@
/* appelant.c */
#include <stdio.h>
#include <dlfcn.h>
void affichage(char *titre, float vals[4]);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int main(int argc, char *argv[])
{
void *handle;
float values[4];
void (*funcname)(const char*, const float *);
handle = dlopen("./plugiciel.so", RTLD_LAZY);
if (!handle) {
/* fail to load the library */
fprintf(stderr, "Error: %s\n", dlerror());
return 1;
}
*(void**)(&funcname) = dlsym(handle, "affichage");
values[0] = 13.37; values[1] = 16.64;
values[2] = 3.14159; values[3] = 0.5;
funcname("rgb * a =", values);
return 0;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */

12
code/plugiciel.c Normal file
View File

@ -0,0 +1,12 @@
/* plugiciel.c */
#include <stdio.h>
#include "plugiciel.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void affichage(char *titre, float vals[4])
{
printf("%s : %f %f %f\n", titre,
vals[0]*vals[3], vals[1]*vals[3], vals[2]*vals[3]);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */

1
code/plugiciel.h Normal file
View File

@ -0,0 +1 @@
void affichage(char *titre, float vals[4]);