2010-03-22 6 views
4

J'essaie d'obtenir du code FORTRAN pour appeler quelques fonctions C++ que j'ai écrites (c_tabs_ étant l'une d'entre elles). Lier et tout fonctionne bien, tant que j'appelle des fonctions qui n'appartiennent pas à une classe.Utiliser Fortran pour appeler les fonctions C++

Mon problème est que les fonctions que je veux que le code FORTRAN appelle appartiennent à une classe. Je regardais la table des symboles en utilisant nm et le nom de la fonction est quelque chose de laid comme ceci:

00000000 T _ZN9Interface7c_tabs_Ev 

FORTRAN ne me permet pas d'appeler une fonction de ce nom, en raison du trait de soulignement au début, donc je m à perte.

Le symbole pour c_tabs quand il est pas dans une classe est assez simple, et Fortran n'a pas de problème avec elle:

00000030 T c_tabs_ 

suggestions? Merci d'avance.

Répondre

3

Si vous faites en sorte que la routine C++ ait une interface de type C (comme cela a déjà été décrit), vous pouvez utiliser la fonction ISO C Binding de Fortran 2003 pour l'appeler. Avec la liaison ISO C, vous pouvez spécifier le nom de la routine et (dans certaines limites) les types C et conventions d'appel (référence, par valeur) des arguments et retour de fonction. Cette méthode fonctionne bien et a l'avantage d'être une norme, et donc dépendante du compilateur et de la plate-forme, contrairement aux anciennes méthodes d'appel de Fortran. La liaison ISO C est supportée par de nombreux compilateurs Fortran 95, tels que gfortran> = 4.3.

+0

+1 pour suggérer l'utilisation de la liaison ISO C qui rend très simple et robuste ce qui était auparavant plutôt compliqué et fragile. –

+0

Parfait! Ceci est exactement ce que je cherchais. Je jouais avec la création d'une interface C comme Die in Sente dans sa réponse, mais c'est une douleur. Merci beaucoup. –

4

Vous aurez besoin de créer une interface de type c et de l'externaliser. C++ manges noms de méthodes (et fonctions surchargées) pour la liaison. Il est notoirement difficile de lier C++ avec autre chose que C++. Il existe des "moyens", mais je vous suggère fortement d'exporter simplement une interface C et d'utiliser les fonctionnalités standard disponibles dans Fortran.

7

Le nom a été modifié, ce que fait le compilateur C++ pour permettre des choses comme la surcharge de fonctions et la liaison sécurisée. Franchement, il est extrêmement improbable que vous puissiez appeler les fonctions membres de FORTRAN (car FORTRAN ne peut pas créer d'instances de classe C++, entre autres) - vous devriez exprimer votre interface en termes d'API C, qui peut être appelée n'importe où.

3

Vous devez créer des wrappers extern "C" pour gérer tous les détails de l'appel FORTRAN C++, le changement de nom étant le plus évident.

class foo { 
public: 
    int a_method (int x); 
} 

extern "C" int foo_a (foo * pfoo, int * px) { 
    if (NULL == pfoo) 
     return 0; 
    else 
     return pfoo->a_method (*px); 
} 

Notez que les compilateurs FORTRAN transmettent tous les arguments par référence, jamais par valeur. (Bien que l'on me dise que cela ne fait pas strictement partie de la norme FORTRAN.)

+0

Quel genre de vous fait vous demander d'où il va obtenir le pointeur foo? –

+0

Je rendrai pfoo un void * et vous aurez besoin d'une méthode pour créer des objets foo extern "C" void * foo_create() '! –

+0

Comment aurais-je un pointeur vers un objet foo préexistant? –

Questions connexes