Python Ctypes for Advanced Fortran and C++


The cytpes library in python 2.6 and greater allows python to call fortran, c, and c++ functions from a specially compiled library. However the python cytpes library is limited in the datatypes that can be called from those libraries. This tutorial will show how to call derived data types from a fortran library and structs in a c++ in python.

Ctypes Fundamental Data Types

Here is a list of data types that can be passed through the ctypes library. For more information on ctypes please visit the python cytpes tutorial.

ctypes type C type Python type
c_char char 1-character
c_wchar wchar_t 1-character
unicode string
c_byte char int/long
c_ubyte unsigned char int/long
c_short short int/long
c_ushort unsigned short int/long
c_int int int/long
c_uint unsigned int int/long
c_long long int/long
c_ulong unsigned long int/long
c_longlong __int64 or
long long
c_ulonglong unsigned __int64 or
unsigned long long
c_float float float
c_double double float
c_char_p char *
(NUL terminated)
string or
c_wchar_p wchar_t *
(NUL terminated)
unicode or
c_void_p void * int/long
or None

Ctypes in python does not support booleans, derived data types, objects, structs, and other commonly used data types.



Derived Data Type


module ddt
implicit none

type rect !Name of data type
  real :: height
  real :: length
end type rect


subroutine calc_area(rc)
type(rect) :: rc
real area, h, l

h = rc%height
l = rc%length

area = h*l
print *, "The area is", area

end subroutine

end module
gfortran -fpic -c ddt.f90

Because there is no ctype for derived data types in fortran we get around this by making an extra module in fortran that will have subroutines that we will call in python.


module modtest
use ddt


subroutine pcall_area
  type(rect) :: rc
  rc%height = 3.5
  rc%length = 2.5
  call calc_area(rc)
end subroutine

end module modtest
gfortran -fpic -c modtest.f90

Now we compile a library from which our python code will call.

gfortran -fpic -shared modtest.o ddt.o -o

Now we want to see a list of functions and subroutines we can call in our python script from the compiled library

nm | less
0000000000000f0e T ___ddt_MOD_calc_area
0000000000000f3a T ___modtest_MOD_pcall_area
0000000000000f08 t __dyld_func_lookup
0000000000000000 t __mh_dylib_header
                 U dyld_stub_binder
0000000000000ef4 t dyld_stub_binding_helper

We want to call ___modtest_MOD_pcall_area in our python script. In order to do this we need to remove one of the underscores in the front as shown:

#Author: Derek Carr

from ctypes import *

libtest = cdll.LoadLibrary("./")

method = libtest.__modtest_MOD_pcall_area

  print "Passed"
  print "Failed"
chmod 777
 The area is   8.7500000    

Now we have successfully called a subroutine from fortran that uses a derived data type or defined data type and used that subroutine in python.

Struct in C++

Comments are closed.