Appeler une librairie dynamique écrite en C dans Fortran sous Linux - Divers - Programmation
Marsh Posté le 23-11-2011 à 17:50:47
Si ta lib est dans un répertoire de ta variable d'environnement LD_LIBRARY_PATH, tu rajoutes juste -lma_dll et ça devrait marcher (si ton code fortran est bon)
Marsh Posté le 24-11-2011 à 15:37:33
Ok merci beaucoup GrosBocdel! J'ai réussi à compiler mais hélas ça plante à l'exécution...segmentation fault. En fait j'aimerais ne pas utiliser de pointeurs dans ma dll afin d'avoir un code "simple" et surtout couplaple facilement avec d'autres langages (genre C++, VB, Python, Matlab...). Comment pourrais -je adapter mon programme fortran avec cette contrainte? Je n'y arrive pas, car en plus la fonction C appelée info() est de type structure:
#ifndef _VERSION_H_
#define _VERSION_H_
typedef struct numeroversion{
char *v;
}numeroversion;
#endif
static char *version="blabla";
export numeroversion call info_version();
numeroversion call info_version(){
numeroversion retour;
strcpy(retour.v,version);
return retour;
}
Une idée?
Marsh Posté le 24-11-2011 à 16:16:07
ça segfault parce que retour.v n'est pas initialisé.
Pour utiliser strcpy il faut que la zone d'arrivée soit allouée.
donc char v[10] au lieu de char *v et ça devrait(?) fonctionner.
Je ne comprends pas le reste du code.
Marsh Posté le 25-11-2011 à 13:35:36
Merci, en fait j'avais déjà testé avec char v[10] et pareil pour static char version[10] mais ça seg fault aussi. Ca plante après le strcpy de la fonction info(). Je ne comprends pas pourquoi, mais j'imagine qu'il y a un problème de lien avec la librairie? Est-il possible de faire appel à une fonction C sans pointeur qui retourne une structure, dans Fortran?
Pour info je compile avec : gfortran -Bdynamic -fPIC infoversion.f -L. -lma_dll -o test
A l'aide!
Marsh Posté le 25-11-2011 à 13:49:25
Code :
|
Tu as aucun controle sur ce code, il vient de l'extérieur? Ou c'est toi qui code ça?
Parce que c'est pas terrible, la.
A+,
Marsh Posté le 25-11-2011 à 14:04:41
La librairie m'a été fournie mais je dispose des fichiers sources donc je peux éventuellement les modifier. En fait, je cherche à faire appel à la fonction info(), qui est dans main.c. La structure numeroversion est quant à elle définie dans un fichier structure.h. Je (re)précise bien que les chaines de caractères sont maintenant initialisées avec une taille de 10 (plus char*). Toute aide sera la bienvenue concernant le code C, mais à mon avis c'est plutôt le Fortran (que je découvre) qui est mal codé, car je ne sais pas comment appeler correctement la fonction info() et c'est bien là que ça plante à l'exécution (j'ai vérifier avec des print).
program test
use iso_c_binding
implicit none
INTERFACE
FUNCTION info() BIND(C) RESULT (pa)
use iso_c_binding
type(c_ptr):: pa
END FUNCTION info
END INTERFACE
type(c_ptr), target :: pa
character(1, c_char),pointer::fpa(:)
pa=info() => Appel correct?
call c_f_pointer(pa, fpa, [50])
print*, fpa(1:50)
end program test
Merci pour vos réponses rapides en tout cas!
Marsh Posté le 25-11-2011 à 14:19:49
Citation : La librairie m'a été fournie mais je dispose des fichiers sources donc je peux éventuellement les modifier |
Je serais toi, je tenterais avec un truc de la forme
int call info_version(char *ver) {
if (!ver) return -1;
strcpy(ver, version);
return 0;
}
Bref, un truc ou la zone mémoire ou tu copies ta chaîne est dans le programme appelant.
Pour le reste, je connais pas assez les évolutions de fortran pour pouvoir t'aider la, j'en ai plus fait depuis 30 ans (sur cartes perforées à l'époque).
A+,
Marsh Posté le 23-11-2011 à 14:03:08
Bonjour à tous, je demande votre aide car je n'arrive pas à lier une librairie dynamique (ma_dll.so) avec un programme Fortran sous Linux. Je débute en Fortran et je n'ai jamais utilisé de librairie dynamique. Je copie-colle ci joint mon programme info.f dont le but est d'afficher une chaine de caractère (en passant par une structure) présente dans la librairie.
info.f :
program test
use iso_c_binding
implicit none
INTERFACE
FUNCTION info() BIND(C) RESULT (pa)
use iso_c_binding
type(c_ptr):: pa
END FUNCTION info
END INTERFACE
type(c_ptr), target :: pa
character(1, c_char),pointer::fpa(:)
pa=info()
call c_f_pointer(pa, fpa, [50])
print*, fpa(1:50)
end program test
Pouvez-vous m'expliquer comment lier ma libraire avec ce code? Et les éventuelles options de compilation? Pour info je compile avec pgfortran.
Cordialement.