Übergabe eines Strings an Fortran DLL mit ctypes und Python

Ich versuche, eine DLL in Python 2.7 mit ctypes zu laden. Die DLL wurde mit Fortran geschrieben und enthält mehrere Unterroutinen. Ich konnte einige der exportierten Funktionen erfolgreich einrichtenlong unddouble Zeiger als Argumente.

import ctypes as C
import numpy as np

dll = C.windll.LoadLibrary('C:\\Temp\\program.dll')
_cp_from_t = getattr(dll, "CP_FROM_T")
_cp_from_t.restype = C.c_double
_cp_from_t.argtypes = [C.POINTER(C.c_longdouble),
                    np.ctypeslib.ndpointer(C.c_longdouble)]

# Mixture Rgas function
_mix_r = getattr(dll, "MIX_R")
_mix_r.restype = C.c_double
_mix_r.argtypes = [np.ctypeslib.ndpointer(dtype=C.c_longdouble)]

def cp_from_t(composition, temp):
    """ Calculates Cp in BTU/lb/R given a fuel composition and temperature.

    :param composition: numpy array containing fuel composition
    :param temp: temperature of fuel
    :return: Cp
    :rtype : float
    """
    return _cp_from_t(C.byref(C.c_double(temp)), composition)

def mix_r(composition):
    """Return the gas constant for a given composition.
    :rtype : float
    :param composition: numpy array containing fuel composition
    """
    return _mix_r(composition)

# At this point, I can just pass a numpy array as the composition and I can get the 
# calculated values without a problem
comps = np.array([0, 0, 12.0, 23.0, 33.0, 10, 5.0])
temp = 900.0

cp = cp_from_t(comps, temp)
rgas = mix_r(comps)

So weit, ist es gut.

Das Problem entsteht, wenn ich es versucheEin weiterer Unterprogramm aufgerufenFunction2 das braucht ein paar strings als eingabe. Die Zeichenfolgen haben alle eine feste Länge (255) und fragen auch nach der Länge der einzelnen Zeichenfolgenparameter.

Die Funktion ist in Fortran wie folgt implementiert:

Subroutine FUNCTION2(localBasePath,localTempPath,InputFileName,Model,DataArray,ErrCode)
!DEC$ ATTRIBUTES STDCALL,REFERENCE, ALIAS:'FUNCTION2',DLLEXPORT :: FUNCTION2
Implicit None
Character *255 localBasePath,localTempPath,InputFileName
Integer   *4  Model(20), ErrCode(20)
Real      *8  DataArray(900)

Der Funktionsprototyp in Python ist wie folgt aufgebaut

function2 = getattr(dll, 'FUNCTION2')
function2.argtypes = [C.POINTER(C.c_char_p), C.c_long,
                      C.POINTER(C.c_char_p), C.c_long,
                      C.POINTER(C.c_char_p), C.c_long,
                      np.ctypeslib.ndpointer(C.c_long , flags='F_CONTIGUOUS'),
                      np.ctypeslib.ndpointer(C.c_double, flags='F_CONTIGUOUS'),
                      np.ctypeslib.ndpointer(C.c_long, flags='F_CONTIGUOUS')]

Und ich nenne es mit:

base_path = "D:\\Users\\xxxxxxx\\Documents\\xxxxx\\".ljust(255)
temp_path = "D:\\Users\\xxxxxxx\\Documents\\xxxxx\\temp".ljust(255)
inp_file = "inp.txt".ljust(255)

function2(C.byref(C.c_char_p(base_path)),
                  C.c_long(len(base_path)),
                  C.byref(C.c_char_p(temp_dir)),
                  C.c_long(len(temp_dir))),
                  C.byref(C.c_char_p(inp_file)),
                  C.c_long(len(inp_file)),
                  model_array,
                  data_array,
                  error_array)

Die Zeichenfolgen sind im Wesentlichen Pfade. Die FunktionFunction2 erkennt die Pfade nicht und zeigt eine Fehlermeldung mit einigen nicht lesbaren Zeichen am Ende an, wie zum Beispiel:

forrtl: severe (43): file name specification error, unit 16, D:\Users\xxxxxxx\Documents\xxxxx\ωa.

Was ich wollte, war die Funktion zu erhaltenD:\Users\xxxxxxx\Documents\xxxxx\. Offensichtlich werden die Zeichenfolgen nicht korrekt übergeben.

Ich habe gelesen, dass Python verwendetNULL Abgeschlossene Zeichenfolgen. Kann dies ein Problem sein, wenn Zeichenfolgen an eine Fortran-DLL übergeben werden? Wenn ja, wie komme ich darum herum?

Irgendwelche Empfehlungen?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage