IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Utilisation d'une fonction de bibliothèque qui change de nom


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Utilisation d'une fonction de bibliothèque qui change de nom
    Hello,

    J'ai une application qui utilise une bibliothèque dont le codeur est quelque peu cavalier, et qui change les noms de fonction sans trop de soucier des implications.

    Une version donnée de mon application doit pouvoir utiliser une version quelconque de cette bibliothèque. Je sais à partir de quelle version de la bibliothèque ont lieu les changements de noms de fonction.

    Sachant que je la bibliothèque a une fonction fournissant son nom de version, est-il possible, à l'exécution, de faire un branchement dans le code pour gérer ça ?

    Le problème est que mon code n'est "linkable" que pour pour une version donnée de l'API. Comment faire ??

    Merci !

  2. #2
    Membre expérimenté Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Par défaut
    1ère Solution change de bibliothèque/de codeur
    2ème solution, sous Windows, tu peux charger explicitement la bibliothèque et obtenir un pointeur sur chaque fonction manuellement (pratique si tu en as 100 ).
    3ème solution, faire 2 versions de ton programme, une avant changement et l'autre après.

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Pour charger une bibliothèque, on utilise LoadLibrary / GetProcAddress sous Windows, dlopen / dlsym sous unixoïdes.

    Après, il faut savoir que demander l'adresse d'une fonction qui n'existe pas renvoie juste NULL, ça pourrait permettre de déterminer la version de la bibliothèque (mais le mieux, c'est d'avoir une fonction get_version).

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Tu peux même faire un code auto-adaptable : tenter de charger la fonction initiale, si ça foire (retour de GetProcAddress valant NULL) tu tentes la "nouvelle", si ça re-foire tu déclares réellement l'erreur à l'utilisateur (à priori, DLL corrompue et/ou trop "nouvelle").

    Le fait que l'application tourne en mode console ou pas n'a absolument aucune importance, LoadLibrary et GetProcAddress sont certes des fonctions de l'API Win32, mais elles n'exigent aucunement la moindre interface graphique (ni même la présence d'une console, d'ailleurs).
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    À priori, c'est effectivement le comportement que je souhaite.

    Je m'y connais fort peu en chargement dynamique de bibliothèque.
    L'API me fournit des .h, un .lib, et un .dll. Jusqu'à présent, j'utilisais bêtement les .h et le .lib. Je suppose que le .dll offre exactement les mêmes services, mais est chargeable dynamiquement avec l:es fonctions que vous évoquez ?

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par oodini Voir le message
    L'API me fournit des .h, un .lib, et un .dll. Jusqu'à présent, j'utilisais bêtement les .h et le .lib. Je suppose que le .dll offre exactement les mêmes services, mais est chargeable dynamiquement avec l:es fonctions que vous évoquez ?
    Le .LIB permet de lier la DLL à l'exécutable de façon "statique" (oui, je sais, ça parait bizarre à lire), dans le sens où l'exécutable devient publiquement dépendant de la DLL et ne peut plus démarrer sans elle (sauf cas particulier de delayed loading, mais qui ne permettrait pas de résoudre ton problème quoi qu'il en soit). De plus, ce .LIB permet aussi d'exporter de la DLL des entités qui ne sont normalement pas exportables, tel que des classes C++ ou des variables globales. Comme tu es en C, seul les variables globales pourraient poser un problème.

    En gros, le principe se résume ainsi :
    • Ne plus inclure le .LIB dans ton projet.
    • "Traduire" le .H actuellement fourni vers un .H d'importation : tes fonctions vont devenir, pour chacune, un "couple" pointeur fonctionnel / type fonctionnel.
    • Un fichier .C devra contenir les variables fonctionnelles ainsi déclarées. Il faudra initialiser chacun de ces pointeurs de fonctions à NULL, par propreté.
    • L'édition de lien se passera sans problème, car ton .H fourni avec ta DLL trouvera ses petits dans ton fichier .C, sous forme de pointeurs de fonctions (qui ne valent rien de bon pour le moment, bien sûr).
    • Dans tes .C/.H nouvellement créés, tu vas ajouter une fonction du genre "int LoadMyDLL(char* DllName)", que tu appelleras au début du main(), destinée à connecter la DLL.
    • Pour chaque fonction, tu vas charger la fonction correspondante de la DLL, ou la "nouvelle" si cela échoue. A la fin de la chaîne de tentatives de chargement, tu testes si ton pointeur de fonction est NULL ou pas : si oui, c'est une erreur critique (=> boum), sinon, la fonction est correctement connectée.
    • Éventuellement, au lieu de provoquer une erreur, tu peux connecter la fonction manquante à une fonction stub, qui affichera un message du genre "Function XXXX is missing, please check version of YYYYY.dll"
    • Le principe est le même pour les variables globales, la différence étant dans le fait qu'il faut caster comme un goret et utiliser quelques trucs sales pour changer l'adresse de ta globale (ou alors, n'utiliser que le pointeur et devoir donc modifier le code utilisant ladite globale).
    • Le reste du programme ne devrait pas avoir besoin d'être modifié, et continuera à ne référencer que le .H d'origine. Seul le fichier contenant le main() devra explicitement faire référence à TON module de chargement.


    Si tu es à l'aise avec les outils de génération automatique de code et/ou les analyses de texte, tu peux même automatiser complètement la création de ces fichiers de chargement : après tout, c'est déjà ce que fait Visual C++ lorsqu'il compile la DLL, la seule différence étant qu'il n'est pas tolérant à la faute contrairement à ce que permettra ton importation manuelle. Cerise sur le gâteau, ton code d'importation est compatible avec GCC si besoin, voire d'autres langages, si la DLL n'utilise pas de conventions d'appel exotiques ou de name-mangling.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Grulim Voir le message
    1ère Solution...
    2ème solution...
    3ème solution...
    La 1ère solution n'est pas envisageable. :-)

    La 2ème solution ne me semble pas applicable, car mon programme est en mode console.

    La 3ème solution est celle que j'applique actuellement, mais elle ne me satisfait pas.

    Sachant que mon application est en fait appelée par un programme Java, peut-être devrais-je me débarrasser de cette appli en C, la transposer en Java, et utiliser JNA pour appeler l'API C...

    Et suite à la réponse de mabu, tout semble en effet laisser penser qu'il faut effectivement passer en Java, qui via JNA offre à peu près la même chose.

  8. #8
    Membre expérimenté Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Par défaut
    Citation Envoyé par oodini Voir le message
    La 2ème solution ne me semble pas applicable, car mon programme est en mode console.
    ??? Je parle de l'OS quand j'écris Windows...

Discussions similaires

  1. Réponses: 5
    Dernier message: 22/04/2013, 14h10
  2. [XL-2007] Mettre variables dans une matrice qui est utilisée par une fonction
    Par Agalis dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 03/04/2012, 09h08
  3. Utilisation d'une fonction codee dans une bibliothèque .so
    Par vandamme dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 21/08/2007, 10h02
  4. Utilisation d'une fonction Transact-SQL ds une requête SQL
    Par Fl0ppeur dans le forum Langage SQL
    Réponses: 1
    Dernier message: 21/02/2006, 13h42
  5. Utilisation d'une fonction dans une procedure
    Par MaxiMax dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 09/08/2005, 15h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo