Comment appeler une bibliothèque écrite en C ++ à partir de C?

Cela me semble une évidence, mais je ne trouve aucune information contre ou pour elle.

Du sharepoint vue de la démêlage, etc., je ne suppose pas que ce soit un gros problème, mais je ne peux pas comprendre comment je peux écrire un tout petit programme C qui appelle une fonction depuis une petite bibliothèque C ++.

Je suis sur Linux en ce moment, j’essaie avec une liaison statique.

Ce doit être quelque chose que beaucoup de gens rencontrent ou un grand nombre de livres, mais je me sens comme un aveugle assis devant ce problème. Fait intéressant, il n’ya pas de question de ce type sur SO.

Je ne sais même pas si cela peut fonctionner, beaucoup moins comment cela doit être fait.

    En règle générale, vous devez forcer le compilateur C ++ à construire la bibliothèque avec une liaison C pour les fonctions exscopes.

    Vous pouvez le faire en procédant comme suit dans votre en-tête:

     #ifdef __cplusplus extern "C" { #endif void func(void); /* ... Other function defs go here ... */ #ifdef __cplusplus } #endif 

    Normalement, l’éditeur de liens applique une modification de nom C ++ aux fonctions afin que l’éditeur de liens C ne puisse pas les trouver. extern "C" oblige à ne pas le faire. Vous devez l’envelopper dans le #ifdef , parce que l’ extern "C" n’est pas valide dans le C.

    METTRE À JOUR

    Comme Charles Salvia le dit dans un commentaire ci-dessous, vous devez vous assurer qu’aucune exception ne sortira par votre interface, car C n’a aucun moyen de les gérer (du moins, pas de manière indépendante de la plate-forme).

    Si la bibliothèque C ++ ne fournit pas d’interface C, c’est impossible.

    Si c’est le cas, utilisez l’interface C.

    Si vous êtes l’auteur, utilisez la fonction extern "C" . http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

    Personnellement, j’écrirais un fichier C ++ qui exporterait des fonctions utilisant le couplage C. En d’autres termes, écrivez une liaison.

    Sous Linux, vous pouvez obtenir le nom mutilé de vos fonctions C ++ avec la commande

     nm my-tiny-c++lib.a 

    Appelez la fonction depuis C par son nom mutilé, mais ne vous attendez pas à ce que cette astuce soit portable …

    Edit : alors vous devez créer un lien en utilisant g ++, ou avec gcc -lstdc ++

    C’est un problème du sharepoint démêler. Utilisez extern C autour du C ++ que vous souhaitez appeler depuis C.

    La gestion et le démagnétisation n’ont jamais été standardisés en C ++, car ils étaient considérés comme trop dépendants de la plate-forme. Le résultat est que, bien que vous puissiez déterminer le nom de la méthode d’une méthode C ++ en consultant la sortie de l’éditeur de liens, il n’existe aucun moyen portable de trouver le “vrai” nom pouvant être lié à une méthode de fonction C ++.

    Vous pouvez écrire un wrapper C autour de n’importe quelle bibliothèque C ++ disposant d’une API C ++. Le wrapper doit être écrit en C ++.

    Vous pouvez même utiliser vos classes C ++. Vous les déclarez en tant que struct. Certains compilateurs donneront un avertissement si vous faites cela, mais vous pouvez probablement soit désactiver cet avertissement, soit simplement l’ignorer.

    Vous créez maintenant des fonctions libres pour créer un pointeur sur une telle structure (pas une instance, car vous ne voyez pas sa définition complète) et pour vous en débarrasser ainsi que toutes ses méthodes en la prenant comme paramètre.

    Notez que si la classe est dans un espace de noms, vous ne pourrez pas le faire, alors créez votre propre structure qui ne contient que ce membre et utilisez plutôt ce “wrapper”.

    Pour toutes vos fonctions C. dans l’en-tête seulement, mettez

     #ifdef __cplusplus extern "C" { #endif // all your functions #ifdef __cplusplus } #endif 

    L’emballage typique ressemble à ceci:

    —- class_a.hpp —-

     #include "class_a_wrapper" class A { public: int foo(double p); double bar(int x, int y); } 

    —- class_a_wrapper.h —-

     #ifdef __cplusplus extern "C" { #endif struct wrap_A; int wrap_A_foo(struct wrap_A *obj, double p); double wrap_A_bar(struct wrap_A *obj, int x, int y); #ifdef __cplusplus } #endif 

    —- class_a_wrapper.cpp —-

     #include "class_a.hpp" int wrap_A_foo(struct wrap_A *obj, double p) { return (static_castobj)->foo(p); } double wrap_A_bar(struct wrap_A *obj, int x, int y) { return (static_castobj)->bar(x, y); }