|
auteur : Laurent Gomila |
Il arrive que l'on veuille charger une bibliothèque dynamique (.dll, .so) explicitement depuis le code C++, que ce soit pour implémenter un système de plugins ou tout simplement car on ne dispose pas des fichiers de lien statique (.lib, .a).
Cette manipulation est spécifique à chaque système, mais on peut cependant remarquer que les principes et les fonctions mis en jeu sont pratiquement équivalents, au nom près.
En l'occurence, cela se fait en trois étapes :
- Charger la bibliothèque dynamique
- Récupérer les fonctions qu'elle exporte
- Décharger la bibliothèque dynamique
Voici un code qui met en oeuvre ce procédé, avec de simples macros pour prendre en charge plusieurs systèmes (Windows et Linux) et ainsi obtenir un code plus ou moins portable :
Code :
# if defined ( _WIN32 ) | | defined ( __WIN32__ )
# include <windows.h>
# define DYNLIB_HANDLE HMODULE
# define DYNLIB_LOAD ( a ) LoadLibrary ( a )
# define DYNLIB_GETSYM ( a , b ) GetProcAddress ( a , b )
# define DYNLIB_UNLOAD ( a ) ! FreeLibrary ( a )
# define DYNLIB_ERROR ( ) " Unknown Error "
# elif defined ( linux ) | | defined ( __linux )
# include <dlfcn.h>
# define DYNLIB_HANDLE void *
# define DYNLIB_LOAD ( a ) dlopen ( a , RTLD_LAZY )
# define DYNLIB_GETSYM ( a , b ) dlsym ( a , b )
# define DYNLIB_UNLOAD ( a ) dlclose ( a )
# define DYNLIB_ERROR ( ) dlerror ( )
# endif
# include <iostream>
int main ()
{
DYNLIB_HANDLE Lib = DYNLIB_LOAD (" library " );
if (! Lib)
{
std:: cerr < < DYNLIB_ERROR () < < std:: endl;
return EXIT_FAILURE;
}
typedef int (* FuncType)(float );
FuncType Func = static_cast < FuncType> (DYNLIB_GETSYM (Lib, " Function " ));
if (! Func)
{
std:: cerr < < DYNLIB_ERROR () < < std:: endl;
return EXIT_FAILURE;
}
int x = Func (5 .f);
if (DYNLIB_UNLOAD (Lib))
{
std:: cerr < < DYNLIB_ERROR () < < std:: endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
|
La plupart des bibliothèques graphiques encapsulent ces fonctions, comme par exemple wxWidgets (wxDynamicLibrary), Qt (QLibrary), SDL (SDL_LoadObject), etc.
|
|
auteur : Laurent Gomila |
Une fois la fin de fichier atteinte par une première lecture, le flux
se met dans un état invalide, ce qui empêche la réussite de toute
lecture ultérieure.
Afin de pouvoir lire à nouveau le même flux, il faut donc :
- Le remettre dans un état valide (avec la fonction clear)
- Le rembobiner (avec la fonction seekg)
# include <fstream>
# include <iostream>
# include <limits>
int CountLines (std:: ifstream& File)
{
int Count = 0 ;
while (File.ignore (std:: numeric_limits< int > :: max (), ' \n ' ))
+ + Count;
return Count;
}
int main ()
{
std:: ifstream File (" fichier.txt " );
std:: cout < < CountLines (File) < < std:: endl;
File.clear ();
File.seekg (0 , std:: ios:: beg);
std:: cout < < CountLines (File) < < std:: endl;
return 0 ;
}
|
|
Consultez les autres F.A.Q's
Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur.
Copyright © 2008 Developpez LLC.
Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne
peut être faite de ce site ni de l'ensemble de son contenu : textes, documents
et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez
selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.