basé sur Cette question Je comprends le but de la construction dans la liaison des bibliothèques C avec C ++ Code. Supposons maintenant les éléments suivants:
J'ai une bibliothèque partagée '.so' compilée avec un compilateur C ++. L'en-tête a une "conception Typedef" et un certain nombre de déclarations de fonction. Si l'en-tête comprend la déclaration externe "c" ... p> ... Quel est l'effet? Spécifiquement, je me demande s'il y a des effets secondaires néfastes de cette déclaration puisque la bibliothèque partagée est compilée comme c ++, pas c. P> existe-t-il une raison pour avoir la déclaration externe "C" dans ce cas? p> p>
5 Réponses :
Lors de la compilation C ++, le nom de la méthode change (Mangling) - et vous ne pourrez pas appeler cette méthode à partir d'une autre DLL / EXE qui utilise c. P>
Pour conserver le nom de la classe et de la méthode dont vous avez besoin pour les compiler comme "C" sans nom de mangling. p>
La bibliothèque est toujours une bibliothèque C ++, mais elle expose certaines de ses déclarations (l'une dans le bloc externe "C") en tant que méthodes C. P>
Le #Ifdef code> gardé
externe code> La déclaration est de dire aux liens C que les symboles ont des entrées de table de symboles C (interdécites). Le
#Ifdef code> garantit qu'il n'y a aucun effet dans l'unité de code (fichier) compilé par un compilateur C. P>
Ceci est important pour que le compilateur ne nommait pas mangle. C ++ utilise Nom Manglling pour différencier les fonctions avec les surcharges de l'opérateur. P>
Run "/ usr / bin / nm" contre un binaire pour voir ce que C ++ fait avec vos noms de fonction: _Zst8_destroyin9__GNU_CXX17__NORMAL_CXX17__NORMAL_ITERATORIPIST6VectorIAISAIEEEEVOVT_S7_SAIT0_E P>
extern "c" empêche ce nom gergling. p>
IIRC, qui permet au programme de relier dynamiquement des symboles au moment de l'exécution. Il est commun pour les architectures de type "plugin". P>
Merci pour l'info. Je pensais à cela de la perspective du client, y compris l'en-tête, et non la bibliothèque exportant les noms.
Un détriment à utiliser extern "C" code> pour une API C ++ est qu'il vous empêche d'avoir des surcharges de fonction:
extern "C"
{
// ILLEGAL - C linkage does not support function overloading
void foo(int x);
void foo(const char *str);
}
Le point d'utilisation externe "c" code> est destiné à la fois C et C ++ pour partager une API, et c est le dénominateur commun le plus bas, vous devez donc respecter les règles du compilateur C. Si cela était i> a une API C ++, vous n'utiliseriez pas
extern "c" code> et seulement compiler avec un compilateur C ++ et tout irait bien.
@quamrana - et sa question est "Quel est l'effet à une bibliothèque partagée C ++". Il n'est pas clair de la question s'il doit pouvoir appeler sa bibliothèque du code C.
Le Cela signifie que les compilateurs C et C ++ produiront les mêmes symboles dans leurs fichiers d'objets. Quel que soit le compilateur produit du code d'objet pour les fonctions déclarées, tous les fichiers d'objet seront connectés avec succès car les symboles ont le même lien et le même nom. p>
Il ne devrait y avoir aucune incidence sur la liaison statique ou la liaison avec une bibliothèque partagée. P> #Ifdef code> Dans l'exemple signifie que seul un compilateur C ++ verra le fichier
extern code> enroulant le fichier d'en-tête qui signifie qu'il produira des noms non mutilés. Un compilateur C ne voit pas le
extern code> (ce qu'il ne comprendrait pas), mais produit toujours des noms non mutilés. P>
Votre bibliothèque ne sera-elle appelée que de C ++ ou avez-vous également besoin de votre bibliothèque à appeler de C?