Bonjour à tous,

je débute avec Ctypes et j'ai un problème de passage d'un tableau de string d'une ddl Fortran vers python.

j'ai un fichier à lire avec la dll avec la structure suivante :

aaaaa
bbbbb
ccccc
4.0 5.0 6.5
8.0 5.1 6.5
3.0 5.2 6.5

j'essaie de récupérer un tableau de string et un autre tableau de réel avec les codes suivants:


mon code fortran
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 
module read_file
           USE iso_fortran_env
           USE,INTRINSIC :: ISO_C_BINDING
          implicit none
 
 
      contains
 
          subroutine OPEN_FILE(FicWxx,path_cptr,lenpath_cptr)  BIND(C)
			  !DEC$ ATTRIBUTES DLLEXPORT :: OPEN_FILE
              integer (KIND=C_INT)         , intent(in) ,value     :: FicWxx
              type(c_ptr), value :: path_cptr
              integer(c_int), value :: lenpath_cptr
              character(len=lenpath_cptr,kind=c_char), pointer :: PATH
			  logical  :: lexist
 
              call c_f_pointer(path_cptr, PATH)                                   			
 
 
              inquire(file=trim(PATH),exist=lexist)
              if(.not.lexist) then
                  stop
              else
                  open(FicWxx,file=trim(PATH))  
              end if
 
          end subroutine OPEN_FILE
 
!--------------------------- read file   ----------------------------------------
 
 
		  subroutine GET_Char_COL(FicWxx,numel,Py_Elem ) BIND(C) 
			  !DEC$ ATTRIBUTES DLLEXPORT :: GET_Char_COL
 
			  integer (KIND=C_INT)       ,value            , intent(in)    :: FicWxx
			  integer (KIND=C_INT)                         , intent(in)    :: numel
			  type(c_ptr)                , value             :: Py_Elem
              character(KIND=C_char,len=16)      ,pointer   :: Elem  
 
			  integer                                                        :: n
 
			  call c_f_pointer(Py_Elem,Elem)
 
              do n = 1, numel
                 read(FicWxx,*)Elem
             end do 
		  end subroutine GET_Char_COL
 
       !     
          subroutine GET_FLOAT(FicWxx,numel,param) BIND(C)
              !DEC$ ATTRIBUTES DLLEXPORT :: GET_FLOAT
 
              integer, parameter                                       :: Ncol=3
			  integer (KIND=C_INT)   ,value              , intent(in)  :: FicWxx
              integer (KIND=C_INT)   ,value              , intent(in)  :: numel
              real  (KIND=C_FLOAT),dimension(numel,Ncol), intent(out)  :: param
 
              integer                                                  :: n
 
              do n = 1, numel
	            read(FicWxx,*) param(n,:)
              end do
 
          end subroutine GET_FLOAT
 
      end module read_file
mon code python:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer
import os
 
 
def Import_DLL():         
 
    PATH = os.path.dirname(os.path.realpath(__file__))
    Lib = ctypes.CDLL(os.path.join(PATH,"./DLL_read.dll"))
    return Lib
 
 
def Decla_Arg():           
 
    Lib.open_file.argtypes = [ctypes.c_int, ctypes.c_char_p,ctypes.c_int]
    Lib.open_file.restype = None
 
    Lib.get_char_col.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int), ndpointer(dtype=np.dtype('a16'))]
    Lib.get_char_col.restype = None
 
    Lib.get_float.argtypes = [ctypes.c_int, ctypes.c_int, ndpointer(dtype=ctypes.c_float)]
    Lib.get_float.restype = None
 
 
def open_file(FicWxx,PATH):
    Lib.open_file(FicWxx,PATH.encode("utf-8"),len(PATH))
    return
 
def get_char_col(FicWxx,nliais):
    z=[' ' for i in range(nliais)]
    #z=[]
    elem=np.asarray(z, dtype = np.dtype('a16'))
    print(elem)
    nliais = ctypes.c_int(nliais)
    Lib.get_char_col(FicWxx, nliais, elem)
    return elem
 
def get_res_type(FicWxx, nliais):
 
    param=np.zeros(shape=(3 , nliais),dtype=ctypes.c_float)
    nliais = ctypes.c_int(nliais)
    Lib.get_float(FicWxx, nliais,param)
    return param
 
# --------------  ___main___  --------------------------------
if __name__ == "__main__":
 
    Lib=Import_DLL()
    Decla_Arg()
    nliais=3
    FicWxx = 15
    PATH =".......\\test.txt"
    open_file(FicWxx,PATH)
 
    elem = get_char_col(FicWxx, nliais)
    print("elem =", elem)
 
    param = get_res_type(FicWxx, nliais)
    print("param =", param)
j'ai une erreur : in get_char_col
Lib.get_char_col(FicWxx, nliais, elem) -> OSError: exception: stack overflow.

PS: si j'ai un fichier sans les string , le code marche bien pour récupérer que le tableau de réel.

Merci pour votre aide.