2017-03-29 3 views
0

J'ai ce module Fortran:Interfacing Python avec module Fortran par ctypes

MODULE utils 
    IMPLICIT NONE 
    PUBLIC 
    INTEGER :: num_atom ! number of atoms in one configuration 
    CONTAINS 
     SUBROUTINE readin 
     IMPLICIT NONE 
     INTEGER :: iargc, ndim, i 

    END SUBROUTINE readin 

    SUBROUTINE convert 
    IMPLICIT NONE 
    REAL :: x,y,z 
    END SUBROUTINE convert 

Je compilez par:

gfortran -shared -fPIC -cpp -O2 thiscode.f90 -o somelib.so 

Ainsi, tout en essayant d'appeler la fonction "readin" de ce qui suit code python:

import os 
_path = os.path.dirname(os.path.realpath(__file__)) + "/" + "somelib.so" 

from ctypes import cdll, byref, c_int, c_double, c_char 
lib_polint = cdll.LoadLibrary(_path) 

def A(): 
    a = lib_polint.readin_ 

A() 

Je ne peux pas identifier le nom de la fonction dans « somelib.so » et l'erreur suivant apparaît:

"undefined symbol: readin_".

Si je retire le module et que je garde juste le sous-programme "readin", cela fonctionne. Comment gérer cela?

Répondre

0

Dump les symboles de la bibliothèque partagée

$ nm -D somelib.so 
0000000000201020 B __bss_start 
       w __cxa_finalize 
0000000000201020 D _edata 
0000000000201028 B _end 
00000000000006f4 T _fini 
       w __gmon_start__ 
00000000000005a0 T _init 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
       w _Jv_RegisterClasses 
00000000000006e0 T __utils_MOD_convert 
0000000000201024 B __utils_MOD_num_at 
00000000000006f0 T __utils_MOD_readin 

On dirait d'avoir votre sous-routine dans un module affecté le nom du symbole. Au lieu de readin_ vous avez __utils_MOD_readin. Si vous supprimez le module environnant et laissez vos sous-programmes au niveau supérieur, vous obtiendrez les noms de symboles que vous attendiez.

Pour le compte rendu, je ne fais que rapporter ce que je vois sur mon système. Je ne suis pas familier avec fortran et je ne sais pas si vous pouvez compter sur cette dénomination à travers les compilateurs.

0

Utilisez l'interopérabilité Fortran avec C pour définir les symboles de l'éditeur de liens pour être tout ce que vous voulez

SUBROUTINE readin bind(C, name="readin") 
    INTEGER :: iargc, ndim, i 

END SUBROUTINE readin 

Maintenant, le nom du sous-programme comme une fonction C externe visible sera juste readin et vous n'avez pas s'inquiéter du nom mangling.

Sans modules, vous pouvez en quelque sorte parier que le nom est _readin mais il peut également être readin_ ou _readin_, mais pas si souvent.

Avec les modules c'est une loterie, le nom mangling diffère vraiment entre les compilateurs. Aucun point utilisant ces symboles _MOD_.