I'm trying to pass arguments to a Fortran subroutine in a shared library using ctypes. Now here's my simple fortran code:
MODULE test_module
INCLUDES
SUBROUTINE fstr_test(file_or_extension, ierr, iopen)
IMPLICIT NONE
INTEGER, INTENT(out) :: ierr
INTEGER, OPTIONAL :: iopen
CHARACTER(LEN=*), INTENT(in) :: file_or_extension
WRITE(6,*) file_or_extension,ierr,iopen
RETURN
END SUBROUTINE fstr_test
END MODULE test_module
I compile this with
gcc -shared -fPIC -o libtest.o fstr_test.f90
This seems to work fine, I can in fact load the shared library in Python 3. Here's non-crashing code:
from ctypes import *
libtest = cdll.LoadLibrary("libtest.so")
f = libtest.test_module_MOD__fstr_test
file = b'wout_li383.nc'
ierr = c_int(0)
iopen = c_int(0)
cfile=c_char_p(b"test_str")
f(cfile,byref(ierr),byref(iopen))
However, I can't seem to pass the string properly. In the form above the string is empty and the two integers print properly to the console. Basically the only progress I'm made is getting Python to crash. I tried the solution here:
Passing string to Fortran DLL using ctypes and Python
but it doesn't seem to work for me, maybe because it's talking about Python 2?
For example
f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(c,byref(ierr),byref(iopen))
Doesn't crash the kernel but the string is empty. Changing to byref:
f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(byref(c),byref(ierr),byref(iopen))
same effect. Now if I try to pass the length by adding the length argument and passing it I get a message of a "Dead Kernel" and I have to restart the kernel. There's no error message per-se.
f.argtype = [c_char_p,c_int,c_int_c_int]
file = b'text.txt'
c = c_char_p(file)
c_len = c_int(len(file))
f(c,byref(c_len),byref(ierr),byref(iopen))
Hope this clarifies. I'm not getting an error message, the kernel is just dying.