Forcer le nom se déformant dans une DLL x64

Je porte une application 32 bits en 64 bits. L’application prend en charge les plugins qui sont des DLL. Malheureusement, l’une des fonctions obligatoires dont chaque plug-in a besoin est appelée FreeLibrary qui est bien sûr en conflit avec l’API kernel32 du même nom. La raison pour laquelle mon API de plug-in utilise le nom FreeLibrary est que l’application a été créée sur une plate-forme différente où FreeLibrary ne se heurte à aucune des API du système d’exploitation.

Toutefois, même sous Windows 32 bits, FreeLibrary n’est pas un problème, car les DLL 32 bits utilisent le nom mangling, c’est-à-dire que la fonction est stockée sous le nom _FreeLibrary et n’est donc pas kernel32 avec l’API kernel32 .

Sur 64 bits, cependant, j’ai un problème maintenant parce que 64 bits ne semble pas utiliser le nom mangling. Sur un compilateur 64 bits, le compilateur crée un symbole appelé FreeLibrary . Ce dernier se heurte bien entendu à l’API kernel32 du même nom et refuse d’établir une liaison, ce qui entraîne l’erreur suivante:

 Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. kernel32.lib(KERNEL32.dll) : error LNK2005: FreeLibrary already defined in test.o Creating library test.lib and object test.exp test.dll : fatal error LNK1169: one or more multiply defined symbols found 

Par conséquent, je me demande s’il existe un moyen de forcer les DLL x64 à utiliser le changement de nom comme sur 32 bits afin que ma DLL puisse exporter un symbole appelé FreeLibrary sans aucun conflit avec kernel32 ?

Ou existe-t-il une autre solution pour contourner ce problème?

La seule solution que je vois est de renommer FreeLibrary en quelque chose qui ne se heurte pas aux API de système d’exploitation pour les versions x64 de mon application, mais je voudrais bien sûr éviter cela car cela réduit la cohérence de l’API de plug-in de mon application. Si possible, j’aimerais conserver le nom de FreeLibrary sur toutes les plates-formes et architectures.

Des idées? J’imagine que s’il était possible d’utiliser des noms réservés tels que FreeLibrary dans une DLL sur 32 bits, il devrait exister un moyen de le faire également sur 64 bits, n’est-ce pas? Mais je ne vois pas comment …

Je n’essaierais pas de convaincre le compilateur de modifier les noms des fonctions. De cette façon se trouve la folie.

Pour clarifier, votre seul problème concerne les symboles en double lors de la liaison de DLL de plug-in. L’application elle-même ne devrait pas se préoccuper du nom des fonctions, car elle appellera les points d’entrée du plug-in via les pointeurs de fonction reçus via GetProcAddress .

En supposant que les plugins n’aient jamais besoin d’appeler les API Windows implémentées dans kernel32.dll, vous pouvez essayer d’omettre kernel32.dll à partir de la commande de l’éditeur de liens. (Voir l’option /NODEFAULTLIB .) Si kernel32.dll ne fait pas partie du lien, il ne devrait y avoir aucune collision.

Mais cela ne fonctionnera pas car /MT dans la ligne de commande implique que vous dépendiez de la bibliothèque d’exécution C, qui dépend à son tour de certaines API kernel32.dll. (De plus, êtes-vous sûr de vouloir lier les plug-ins à la bibliothèque d’exécution statique et non à la version de la DLL?)

L’option restante consiste donc à modifier le nom de la fonction. Cela devrait être sortingvial, puisque vous portez quand même. Vous pouvez même utiliser le préprocesseur pour pirater le nom lors de la compilation des plugins, de sorte que vous n’ayez pas besoin de changer leur code source:

 cl /EHsc /c /DFreeLibrary=Plugin_FreeLibrary /Fotest.o test.c 

Ensuite, modifiez l’appel GetProcAddress dans l’application pour rechercher Plugin_FreeLibrary au lieu de FreeLibrary , ce qui, je suppose, se produit à un seul endroit.