Using ctypes in Python - arrays and structures

Dec 7, 2011
Reaction score
Hello Folks!

I try to call from Python several routines contained in a .so library generated from some Fortran 90 routines. All the objects in the library are resolved using the -fPIC flag when compiling the .so.

I have a sample code which looks like

#!/usr/bin/env python3

from numpy import *
from ctypes import *

lib_test = cdll.LoadLibrary("./")

method = lib_test.__test_MOD_wrap_xbelem
method.restype = None

MaxElNod = 3
NumElems = 2
NumNodes = (c_int *NumElems)()
Length   = zeros(NumElems, dtype=double, order="Fortran")
RBMass   = zeros((MaxElNod*NumElems,6,6), dtype=double, order="Fortran")

# Call the function in the .so
method(byref(c_int(NumElems)), byref(NumNodes), Length.ctypes.data_as(POINTER(c_double)), RBMass.ctypes.data_as(POINTER(c_double)) )
I have few questions I hope you can help.

1) The code works fine as given above. However, I would like to pass the integer array as done with the array of type double. I would be keen to have a code which looks more like this

NumNodes = zeros(NumElems, dtype=int, order="Fortran")

method(byref(c_int(NumElems)), NumNodes.ctypes.data_as(POINTER(c_int)), Length.ctypes.data_as(POINTER(c_double)), RBMass.ctypes.data_as(POINTER(c_double)) )
In this second case, the array NumNodes is equal to array([8589934594, 0]), whereas both elements of NumNodes should be equal to 2. I haven't said earlier, but NumNodes is only initialized in Python and it gets the values in the Fortran90 where they are computed in correct way. The correct results are produced with the first sample code. I am not able to figure out what I miss, as I presumed that the similar operations performed on the arrays of type double could be applied to arrays of type int.

2) The other question I have is about derived types. The Fortran 90 code makes use of derived types, and this is the reason that we have decided to create a .so library out of it to work with Python. At the moment, the Python script does not work with a corresponding structure and the fields of the derived types have been given each to a separate variable. This means that several input arguments are passed to a wrapper in the .so, and then appropriate fields are compacted to form a derived type in Fortran90. Arrays are also converted to multi-dimensional entities when it is the case.

I suppose I can ask for your expertice on how some tips. Imagine in Fortran90 there is a derived type of the form

 type xbelem
  integer:: NumNodes
  real(8):: Length
  real(8):: RBMass(MaxElNod,6,6)
 end type xbelem
which is used in some routines, and it is initialized as

type(xbelem),intent(inout):: Elem(NumElems)
What is the similar structure in Python? and how to pass it to the .so library?

I would like to thank you for any help.
Kind regards,


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question