2009-03-04 3 views
3

Pouvez-vous appeler des fonctions C++ à partir d'Ada?Pouvez-vous appeler des fonctions C++ à partir d'Ada?

Je me demande s'il existe un moyen de le faire directement, sans faire l'implémentation en C et en écrivant un wrapper C++ & et un wrapper Ada, par ex. Je voudrais aller C++ -> Ada plutôt que C++ -> c -> Ada.

+0

Il existe plusieurs systèmes d'exploitation dans le monde. Il existe plusieurs implémentations C++. Il existe plusieurs implémentations Ada. Ce que vous demandez n'est pas une définition de la langue, mais une mise en œuvre. Vous devez inclure plus de détails. –

+0

Je suis confus. La question commence en disant que vous voulez aller Ada-> C++, mais finit par dire que vous voulez aller C++ -> Ada. Ce sont des choses très différentes. –

+0

J'aurais dû clarifier cette notation ... ici le -> signifie "importé par" ou "appelé par". Ce que je voulais savoir, c'était que je ne voulais pas avoir à écrire des C wrappers dans mon C++ pour entrer dans Ada, mais aller directement. Sry n'était pas très clair. – paxos1977

Répondre

4

Le problème avec Ada à C++ est que C++ ne pas un ABI défini.
Chaque compilateur est autorisé à définir l'ABI le plus efficace possible. Ainsi, l'interfaçage avec d'autres langages (Ada) est pénible car vous auriez besoin de votre compilateur Ada pour savoir avec quel compilateur le C++ a été compilé avant de pouvoir générer le code correct pour appeler n'importe quelle méthode/fonction C++. D'autre part, le C ABI est un standard bien défini pour tous les compilateurs et, en tant que tel, fournit une interface pratique et agréable pour toute langue à laquelle se connecter.

+1

La norme C, comme la plupart des langages, ne définit aucun ABI. Le C ABI est à peu près "l'assemblage de votre CPU et de votre OS"; juste sur x86, vous avez au moins quatre conventions d'appel de procédure différentes (stdcall, cdecl, thiscall, fastcall, ...) –

+0

Michael Ratanapintha: Le standard C définit un ABI. Il définit comment les paramètres sont associés aux fonctions. Où l'adresse de retour est stockée et où le résultat d'un appel fucntion peut être trouvé. La même convention est utilisée pour tous les compilateurs. –

+0

@Martin: Euh, quoi? –

1

Il ne semble pas possible ...

Informations here

"Interface directe vers C++ de Ada est en dehors du champ d'application de l'Ada (au moins 95)"

+0

Cela signifie simplement qu'il n'y a pas de façon * standard * de le faire, pas que ce soit impossible. –

0

Green Hills Software a également publié un excellent PDF à ce sujet.
http://www.ghs.com/download/whitepapers/ada_c++.pdf

+0

Err ... Non. Green Hills n'utilise pas GCC. Ils ont leur propre compilateur qui, je crois utilise l'interface Itermetrics (maintenant SofCheck?). Cependant, une grande partie de l'information dans ce PDF est en réalité indépendante du compilateur. Ada spécifie une quantité surprenante de ce genre de choses dans la norme. –

1

Je ne l'ai pas touché depuis Ada 99/00 si ma mémoire est peut-être un peu louche mais quand nous travaillions sur une application Windows graphique en Ada nous avions besoin de faire des choses en C++ (mission non critique) et la façon dont nous avons incorporé les deux était d'avoir les trucs c + + dans une DLL et ensuite créer un wrapper C à cette DLL et ensuite utiliser une interface pragma qui spécifiait le wrapper c et ensuite nous pourrions appeler les méthodes dans la DLL depuis cette interface.

Je pense que cela équivalait à une triple maintenance car les signatures de méthodes devaient être mises à jour dans l'interface pragma et l'encapsuleur C si elles changeaient dans la DLL C++.

Fondamentalement, c'était une douleur. Je pense que nous devions utiliser une directive Win32 Lean et Mean precomplier dans l'encapsuleur C.

De toute façon, c'est tous les trois d'entre nous qui ont travaillé sur le projet peuvent se souvenir.

+1

Vous avez seulement besoin de faire cela dans Windows si vous utilisez gcc pour compiler un côté et VisualC++ pour compiler l'autre. Même le compilateur C/C++ de gcc aurait ce problème. La raison en est que gcc et Microsoft utilisent des linkers différents. Si vous utilisez un compilateur Ada qui utilise l'éditeur de liens Microsoft (comme ObjectAda), vous ne rencontrez pas ce problème. Si vous restez hors de Windows, vous n'avez pas ce problème. :-) –

1

rasade pourrait être en mesure de le faire

4

La seule réponse vraiment compilable-agnostique que je peux vous donner est que c'est aussi simple que d'appeler C++ de C sur votre système. Tout comme avec C, vous devez trouver le symbole brouillé par le nom de votre routine C++ et écrire une liaison sur le côté C (dans ce cas, le côté Ada) qui lie à ce nom tronqué. Vous devrez également probablement faire certaines choses du côté C++, comme déclarer la fonction C++ extern.

Si vous pouvez déclarer votre fonction C++ externe "C", c'est facile. Faites-le simplement du côté C++ et utilisez les fonctions d'importation C standard d'Ada côté Ada.

Exemple:

dans votre cpp:

extern "C" int cpp_func (int p1, int p2) { 
    ; // Whatever.. 
} 

dans votre .adb:

function cpp_func (p1, p2 : Interfaces.C.Int) return Interfaces.C.Int; 
pragma Import (C, cpp_func); 

... 
Result : constant Interfaces.C.Int := cpp_func (1, 2); 
2

Vous pourriez être intéressé par cet article, qui traite d'un niveau d'objet de liaison de Ada en C++:

http://www.adacore.com/uploads/technical-papers/Class_level_interfacing.pdf

En outre, la version récente de GNAT dispose d'un puissant générateur de liaison automatique.

+0

Votre URL n'est pas correcte. Il devrait être http://www.adacore.com/uploads/technical-papers/Class_level_interfacing.pdf – qunying

+0

Aussi, pour gcc et gnat, http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Interfacing-with-C_002b_002b- At-the-Class-Level.html – qunying

Questions connexes