DLL C++ à l'Exportation: Décoré/noms Déformés
Créé de base de C++ DLL et exporté à l'aide de noms de fichier de Définition de Module (Madll.def).
Après la compilation j'ai vérifier les noms des fonctions exportées à l'aide de dumpbin.exe
Je m'attends à voir:
SomeFunction
mais je vois ceci à la place:
SomeFunction = SomeFunction@@@23mangledstuff#@@@@
Pourquoi?
La fonction exportée apparaît sans décor (surtout par rapport à la non-utilisation du Module fichier Def), mais qu'est-ce autre chose?
Si j'utilise dumpbin.exe
contre une DLL à partir de toute application commerciale, vous obtenez le nettoyer:
SomeFunction
et rien d'autre...
J'ai aussi essayé de supprimer la Définition de Module et de l'exportation des noms à l'aide de la "C" style de l'exportation, à savoir:
extern "C" void __declspec(dllexport) SomeFunction();
(Simplement à l'aide de "extern "C" ne pas créer une fonction exportée)
Cependant, cela crée toujours le même résultat, à savoir:
SomeFunction = SomeFunction@@@23mangledstuff#@@@@
J'ai aussi essayé la #define dllexport __declspec(dllexport)
option et créé une LIB avec aucun problème. Cependant, je ne veux pas avoir à fournir un fichier LIB pour les personnes à l'aide de la DLL dans leur application en C#.
C'est une plaine de vanille DLL C++ (code non managé), compilé en C++ rien, mais un simple en-tête et le code. Sans Module Def-je obtenir de déformation des fonctions exportées (je peux créer une bibliothèque statique et l'utilisation de la LIB aucun problème. J'essaie d'éviter). Si j'utilise extern "C" __declspec(dllexport)
OU une Définition de Module-je obtenir ce qui semble être un non nom de la fonction... le seul problème, c'est qu'il est suivi par un "=" et ce qui ressemble à un décoré de la version de la fonction. Je veux me débarrasser de la substance après le "=" - ou au moins de comprendre pourquoi il est là.
Comme il est, je suis à peu près certain que je peux appeler la fonction à partir de C# à l'aide d'un P/Invoke... je veux juste éviter de bric-à-brac à la fin du "=".
Je suis ouvert aux suggestions sur la façon de modifier le projet/les paramètres du compilateur, mais j'ai juste utilisé le standard de Visual Studio DLL modèle - rien de spécial.
- L'ensemble de point de
extern "C"
est à undecorate fonctions c++. Si ca ne fonctionne pas, vous devez vous assurer que vous êtes en train de construire votre DLL correctement. - Hans donné la bonne réponse ci-dessous.......
- Je veux juste éviter de bric-à-brac à la fin du "=". Cette ordure ne fait pas de mal. Il est là, mais il ne change pas le binaire de l'interface de votre module.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez obtenir ce que vous voulez en éteignant les informations de débogage génération. Projet + Propriétés, Éditeur De Liens, De Débogage, De Générer Des Informations De Débogage = No.
Naturellement, vous ne voulez le faire pour la version Release. Lorsque l'option est déjà défini de cette façon.
extern "C" DllExport
etc. etextern "C" DllImport
etc. avant de vos déclarations de fonction après la définition des macros pour__declspec( dllexport )
et__declspec( dllimport )
. Cela a finalement fonctionné pour moi, cependant, le débogage de truc, qui, par accident, j'ai voté jusqu'n'a pas de travail pour moi. Voir réponse et le commentaire ci-dessus par Ron Warholic.Au lieu de l'aide .fichier def il suffit d'insérer
pragma comment
comme ceEdit: Ou encore plus simple: à l'Intérieur du corps de la fonction utilisation
. . . si vous avez des problèmes à trouver la décorées nom de la fonction. Ce dernier pragma peut encore être réduite à une simple définition de macro.
extern "C"
ne travaille pas pour__stdcall
. Lepragma
crée une seconde entrée dans la liste des fonctions de la DLL exportations. Je souhaite que je pourrais vous donner plus de points!#pragma comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__)
Vous devez déclarer les fonctions que
extern "C"
si vous ne voulez pas que leurs noms soient déformés.De l'expérience, soyez prudent si vous utilisez
__stdcall
dans votre signature de fonction. Avec__stdcall
, le nom restera mutilé dans une certaine mesure (vous trouverez assez rapidement). Apparemment, il y a deux niveaux de déformation, on leextern "C"
traite avec du C++, mais il ne traite pas avec un autre niveau de nom de déformation causée par__stdcall
. Le supplément de déformation est apparemment pertinentes de la surcharge, mais je ne suis pas certain de qui.WINAPI
(qui se traduit par__stdcall
) il y a, mais il n'a pas.Désolé pour la réponse à un vieux thread, mais ce qui a été marqué comme la réponse n'a pas de travail pour moi.
Comme un certain nombre de personnes l'ont souligné, la extern "C" décor est important. La modification du "Projet /Propriétés /Gestionnaire /Débogage /Générer les informations de débogage" définition fait absolument aucune différence à la déformation des noms générés pour moi dans Debug ou Release mode de construction.
De l'installation: VS2005 la compilation d'une Classe Visual C++ de la Bibliothèque de projet. J'ai été vérifier la compilation .sortie dll de Microsoft outil Dependency Walker.
Voici un exemple de recette qui a fonctionné pour moi...
Dans le projet.h:
Dans project.cpp:
Ensuite être appelée à partir de C# code managé, classe.cs:
Faire le ci-dessus a empêché les noms déformés en Debug et Release mode, quelle que soit la génération des informations de débogage de réglage. Bonne chance.
Même sans les mutilations, les 32 bits et les versions 64 bits nom exportations différemment, même avec extern "C". Vérifiez auprès de DEPENDS.EXE.
Cela peut signifier de GROS problèmes à tout client qui ne LoadLibrary+GetProcAdress pour accéder à votre fonction.
Ainsi, en plus de tous les autres utilisent un Fichier de Définition de Module comme suit:
Yeap, c'est un peu une douleur à maintenir, mais alors, combien de fonctions exportées écrivez-vous un jour?
De plus, j'ai l'habitude de modifier les macros comme indiqué ci-dessous, depuis ma Dll exporter les fonctions qui ne sont pas des classes C++ et je veux qu'ils soient remboursables par la plupart des environnements de programmation:
La dernière ligne utilisée pour confondre VisualAssistX il y a quelques années, je ne sais pas si il digère correctement maintenant 🙂
Je sais combien de fois j'ai essayé de forcer les noms de fonction à l'aide de code et #pragma.
Et je termine toujours avec exactement la même chose, à l'aide de Fichier de Définition de Module (*.def) à la fin.
Et voici la raison:
Je me demande pourquoi personne ne l'a fait, il m'a fallu seulement 10 minutes de tester tous les cas.
la SomeFunction@@@23mangledstuff#@@@@ est mutilé à donner le type et la classe de la fonction C++. Le simple exportations sont des fonctions qui sont disponibles à partir de C c'est à dire sont écrites en C ou autre sont déclarées extern "C" dans le code C++. Si vous voulez une interface simple, vous devez faire les fonctions de l'exportation de l'utiliser juste C de types et de les rendre non des fonctions de membre dans l'espace de noms global.
Fondamentalement, lorsque vous utilisez les fonctions en C++, des parties de leurs noms incluent maintenant la date de leur signature et d'autres choses semblables, afin de faciliter la langue des fonctionnalités comme la surcharge.
Si vous écrivez une DLL à l'aide de __declspec(dllexport), puis il devrait également produire une lib. Lien vers cette lib, et vous serez automatiquement liés et les fonctions enregistrées par le CRT à l'heure de démarrage (si vous rappeler de changer toutes vos importations et les exportations). Vous n'avez pas besoin de connaître le nom de déformation si vous utilisez ce système.
Dans le cas où il n'était pas clair à partir de centaines de lignes de gaufre sur le sujet de la déformation des exportations. Voici mon 2c en vaut la peine 🙂
Après la création d'un projet appelé Win32Project2 à l'aide de VS 2012 et en choisissant l'exportation de tous les symboles de l'assistant. Vous devriez avoir 2 fichiers appelés Win32Project2.cpp et Win32project2.h
À la fois de ceux qui vont le faire référence à un exemple exportable variable et un exemple de fonction exportée.
Dans Win32Project2.h vous aurez la suivante:
À unmangle CHANGER les deux dernières lignes pour extern "C" déclarations:
Dans Win32Project2.cpp vous aurez également la suite des définitions par défaut:
À unmangle MODIFIER À:
Essentiellement, vous devez utiliser la extern "C" préfixe de déclarations dans le but d'obliger l'éditeur de liens pour produire unmangled C comme les noms.
Si vous préférez utiliser les noms déformés pour qui peu plus d'obfuscation (dans le cas d'une déformation d'info est utile à quelqu'un en quelque sorte) utiliser "dumpbin exportations Win32Project2.dll" à partir d'un VC de ligne de commande pour la recherche de la référence des noms. Il sera de la forme "?fnWind32Project2@[param octets]@[autres informations] . Il y a aussi d'autres DLL outils de visualisation autour si l'exécution d'un VC shell de commande n'est pas flotter votre bateau.
Exactement pourquoi MS ne fait pas défaut à cette convention est un mystère. La réelle déformation de l'information signifie quelque chose (comme le paramètre de la taille en octets et plus) qui pourrait être utile pour la validation et le débogage, mais sinon guff.
Pour importer la fonction de DLL ci-dessus en C# du projet (dans ce cas, une base de C# application windows avec un formulaire contenant le bouton "bouton1") voici un exemple de code: