2017-03-09 3 views
0

j'ai adapté mon code de cette questionFortran DLL dans wrapper Python, sortie pour même fonction varie

Mon but ultime est de: - emballer un code Fortran dans une DLL (déjà terminé) - créer un Wrapper Python comme une interface pour recevoir des entrées d'une source, et fournir ces entrées dans une DLL et les transmettre dans les DLL Fortran fonction - retourner la sortie de la fonction à transmettre à un autre programme Python. Jusqu'à présent, j'ai utilisé cet exemple comme prototype (pour ce que je vais éventuellement adapter), obtenant des sorties différentes à chaque fois.

comme indiqué ici:

C:\Users\NAME\Desktop>python.exe py_wrapper.py 
    <CDLL 'fort_test', handle 6f800000 at 0x25e174ec2e8> 
    <_FuncPtr object at 0x0000025E17617388> 
    <_FuncPtr object at 0x0000025E17617388> 
    c_long(3) 
    390943376  <---int value (my annotation for clarity) 
    <class 'int'> 
    c_long(390943376) 
    <__main__.LP_c_long object at 0x0000025E174D54C8> 

et

C:\Users\NAME\Desktop>python.exe py_wrapper.py 
    <CDLL 'fort_test', handle 6f800000 at 0x23fa636c2e8> 
    <_FuncPtr object at 0x0000023FA6497388> 
    <_FuncPtr object at 0x0000023FA6497388> 
    c_long(3) 
    -1506454896  <---int value (my annotation for clarity) 
    <class 'int'> 
    c_long(-1506454896) 
    <__main__.LP_c_long object at 0x0000023FA63554C8> 

Voici le contenu de mon code Fortran:

subroutine ex(i) 
    integer i 
    i=i+1 
    return i 
    end  

et voici mon wrapper Python: (il y a beaucoup de trucs de test ici)

from ctypes import * 

    DLL = CDLL('fort_test') 
    print(DLL) 

    print(getattr(DLL, 'ex_')) 
    print(DLL.ex_) 

    x = pointer(c_int(3)) 
    print(x.contents) 
    res = DLL.ex_(x) 
    print(res) 
    print(type(res)) 
    proc_res = pointer(c_int(res)) 
    print(proc_res.contents) 
    print(proc_res) 

Ma question est, est-ce que quelqu'un sait pourquoi cette sortie ne cesse de changer? Mon entrée était 3 dans le code, je m'attendrais à une sortie de quatre étant donné la fonction, mais je reçois ce qui ressemble à des adresses mémoire (voir mes annotations dans les exemples de sortie) ou une représentation entière signée d'une adresse mémoire?

+0

Bien que cela n'a pas d'importance ici, 'return Dans le Fortran, le sous-programme ne signifie probablement pas ce que vous pensez que cela signifie. – francescalus

+0

Oh, j'ai oublié de sortir ça. Je bidouillais avec des trucs, je ne sais pas vraiment fortran cela haha ​​(d'où la raison pour laquelle j'essaye de l'envelopper, le morceau de code que je veux vraiment faire est beaucoup plus grand, et je ne peux pas le poster ici) – Andy

+0

Je ne suis pas familier avec la convention d'appel de Fortan, mais vous * faites * passer un pointeur sur un entier et non sur l'entier réel. Je suppose que vous recevez l'adresse et non la valeur. Avez-vous essayé un simple 'res = DLL.ex_ (3)'? –

Répondre

0

MISE À JOUR:

J'ai résolu mon problème.

from ctypes import * 

DLL = windll.fort_test 
print DLL 

x = byref(c_int(3)) 
print x res = DLL.ex_(x) 
print cast(res,POINTER(c_int)).contents 

J'ai aussi beaucoup nettoyé cela. Je passe encore par référence, puis cast l'adresse de mémoire qui est retournée comme un pointeur c_int (toutes les majuscules sont importantes) et déréférencer en utilisant les pointeurs de fonction '.contents'

+0

Recherchez 'argtypes' et' restype' pour faciliter les appels. –