Appeler une fonction en C

2010

Windows

Appel de fonction avec une bibliothèque dynamique

Chaque fonction est contenue soit dans une bibliothèque statique, soit dans une bibliothèque dynamique. Lorsque la bibliothèque est chargée dynamiquement, le chargeur de programme utilise les primitives suivantes :

  • LoadLibrary

  • GetProcAddress

  • FreeLibrary

ces primitives sont incluses dans la bibliothèque windows.h.

Exemple avec l’appel de la fonction MessageBox :

#include <windows.h>

typedef int (WINAPI* _MessageBoxA)(HWND, LPSTR, LPSTR, UINT);

int main() {
    HMODULE hUser32 = NULL;
    _MessageBoxA __MessageBoxA = NULL;

    hUser32 = LoadLibraryA("user32.dll");
    __MessageBoxA = (_MessageBoxA) GetProcAddress(hUser32, "MessageBoxA");

    __MessageBoxA(NULL, "Hello world", "Information", 64);

    FreeLibrary(hUser32);
    return 0;
}

Exemple avec l’appel de la fonction printf :

#include <windows.h>

typedef int (WINAPI *_printf)();

int main (int argc, char argv) {
    HMODULE hMsvcrt = NULL;
    _printf __printf = NULL;

    hMsvcrt = LoadLibraryA("msvcrt.dll");

    __printf = (_printf) GetProcAddress(hMsvcrt, "printf");

    __printf("L\'adresse de printf est : %X",__printf);

    FreeLibrary(hMsvcrt);

    return 0;
}

Appel de fonction avec une bibliothèque statique

Exemple avec une fonction add définie :

#include <stdio.h>

typedef int (*_add) (int,int);

int add(int nb, int nb1) {
    return nb + nb1;
}

int main() {
    int total = add(5,5);

    _add __add = (int)&add;

    total = __add(5,5);
    printf("%d", total);

    return 0;
}

Avec une fonction dans une bibliothèque dynamique

#include <windows.h>

typedef int (*_printf)();

int main() {
    _printf __printf = 0x77C1186A;
    __printf("Hello world !");

    return 0;
}

Linux

Appel de fonction avec une bibliothèque dynamique

Toute fonction peut être appelée dynamiquement à l’aide des primitives suivantes :

  • dlopen

  • dlsym

  • dlclose

Pour utiliser ces primitives, inclure le fichier suivant dlfcn.h.

Appel de fonction avec une bibliothèque statique

Avec la fonction add

#include <stdio.h>

typedef int (*_add)(int, int);

int add(int nb, int nb2) {
    return nb + nb2;
}

int main(int argc, char argv) {
    int total;

    _add __add = NULL;
    __add = &add;

    total = __add(5,5);
    printf("%d",total);
    return 0;
}

Comment compiler

  • Exemple de bibliothèque

// file : libprintf.c
#include <stdio.h>

void myPrintf(char *chaine) {
    printf("%s", chaine);
}

Le fichier .h

// file : libprintf.h
void myPrintf(char *chaine);
  • Compiler la bibliothèque statiquement

gcc -c libprintf.c -o libprintf.o
ar rcs libprintf.a libprintf.o
  • Créer une bibliothèque dynamique

gcc -c -fPIC libprintf.c -o libprintf.o
gcc -shared -Wl -o libprintf.so.1.0.1  libprintf.o
  • Utiliser la bibliothèque

// file : main.c
#include <stdio.h>
#include "libprintf.h"

int main(int argc, char argv) {
    myPrintf("Hello world");
    return 0;
}
  • Lien entre la bibliothèque statique et le programme utilisateur

gcc -static main.c -L. c_printf.a -o statically_linked
  • Lien entre la bibliothèque dynamique et le programme utilisateur

gcc main.c -o dynamically_linked -L -l c_printf.so.1.0.1