131 votes

Conflit de fonction C

Que dois-je faire si deux bibliothèques fournissent des fonctions avec des noms équivalents?

65voto

Ben Points 3042

Il est possible de renommer des symboles dans un fichier objet à l’aide de objcopy --redefine-sym old=new file (voir man objcopy).

Il vous suffit ensuite d'appeler les fonctions en utilisant leurs nouveaux noms et de les lier au nouveau fichier objet.

61voto

dmckee Points 50318
  • Si vous contrôlez l'un ou les deux: modifier pour changer le nom et le recompiler Ou, de manière équivalente, voir Ben et inconnudes reponses qui vont travailler sans accès au code source.
  • Si vous n'avez pas le contrôle de l'un d'eux, vous pouvez envelopper l'un d'eux. C'est la compilation d'une autre (statiquement!) de la bibliothèque qui ne fait rien à l'exception de la ré-exportation de tous les symboles de l'original, à l'exception de la délinquance, qui est atteint par l'intermédiaire d'un gestionnaire avec un autre nom. Quel tracas.
  • Ajouté plus tard: Depuis qeek dit qu'il est en train de parler des bibliothèques dynamiques, les solutions proposées par Ferruccio et mouviciel sont probablement le meilleur. (J'ai l'air de vivre dans la longue il y a des jours où une liaison statique est la valeur par défaut. C'couleurs de ma pensée.)

A propos du commentaire: Par "exportation" je veux rendre visible pour les modules de liaison de la bibliothèque---l'équivalent de la extern mot-clé à portée de fichier. Comment cela est contrôlé est de l'OS et de l'éditeur de liens dépendante. Et c'est quelque chose que j'ai toujours regarder de très près.

18voto

Ferruccio Points 51508

Sous Windows, vous pouvez utiliser la fonction LoadLibrary() pour charger l'un de ces bibliothèques dans la mémoire et l'utilisation de GetProcAddress() pour obtenir l'adresse de chaque fonction, vous devez appeler et appeler les fonctions par l'intermédiaire d'un pointeur de fonction.

par exemple

HMODULE lib = LoadLibrary("foo.dll");
void *p = GetProcAddress(lib, "bar");
// cast p to the approriate function pointer type (fp) and call it
(*fp)(arg1, arg2...);
FreeLibrary(lib);

serait d'obtenir l'adresse d'une fonction nommée bar dans foo.dll et de l'appeler.

Je sais systèmes Unix support des fonctionnalités similaires, mais je ne vois pas de leurs noms.

9voto

Sniggerfardimungus Points 5207

Voici une pensée. Ouvrez l'une des bibliothèques incriminées dans un éditeur hexadécimal et modifiez toutes les occurrences des chaînes incriminées. Vous devriez alors pouvoir utiliser les nouveaux noms lors de tous les prochains appels.

UPDATE: Je viens de le faire sur cette fin et cela semble fonctionner. Bien sûr, je n'ai pas testé cela à fond - ce n'est peut-être qu'un très bon moyen de se dégourdir les jambes avec un fusil à pompe Hexedit.

8voto

mouviciel Points 36624

Vous ne devriez pas les utiliser ensemble. Si je me souviens bien, l'éditeur de liens génère une erreur dans un tel cas.

Je n'ai pas essayé, mais une solution peut être avec dlopen() , dlsym() et dlclose() qui vous permettent de gérer par programme des bibliothèques dynamiques. Si vous n'avez pas besoin des deux fonctions en même temps, vous pouvez ouvrir la première bibliothèque, utiliser la première fonction et fermer la première bibliothèque avant d'utiliser la deuxième bibliothèque / fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X