Python ctypes: OSError: exception: access violation writing 0x00000000

-1

I'm trying to use ctypes to call a function in a dll built by C. I'm having trouble with the input types and thus the OS error happens. The function arguments in the C code for dll:

DllExport extern double far pascal dFlComprOil (
   int               nOilCompr,    
   double            dOilGrav,    
   double            dSGGas,       
   double            dSolnGOR,     
   double            dTargetPress, 
   double            dTargetTemp,  
   double            dSepPress,     
   double            dSepTemp,     
   BOOL              bCheckRanges, 
   char          far szErrorMsg[], 
   int           far *nError) 

And my code in Python:

from ctypes import *
lib = WinDLL(r"C:\FldSP970.dll")
class SomeStructure(Structure):
    _fields_ = [
    ('nOilCompr', c_int),
    ('dOilGrav', c_double),
    ('dSGGas', c_double),
    ('dSolnGOR', c_double),
    ('dTargetPress', c_double),
    ('dTargetTemp', c_double),
    ('dSepPress', c_double),
    ('dSepTemp', c_double),
    ('bCheckRanges', c_bool),
    ('szErrorMsg[]', c_char),
    ('*nError', c_int)
    ]
lib.dFlComprOil.restype = c_double
lib.dFlComprOil.argtypes = [POINTER(SomeStructure)]
#lib.dFlComprOil.argtypes = c_int,c_double,c_double,c_double,c_double,c_double,c_double,c_double,c_bool,c_char,c_int      
s_obj = SomeStructure(0, 35, 0.65, 151.489, 861.066, 60, 100, 60,False,0,0)
result = lib.dFlComprOil(byref(s_obj))

I have fixed some errors and done experiments for the argument szErrorMsg but it gives this vague OS Error in the end. I'm guessing I'm doing something wrong with the last two arguments, but since I'm not quite familiar with C, I'm now lost. Any help or guidance would be appreciated.

python
ctypes
asked on Stack Overflow Jan 3, 2021 by OliverX

1 Answer

0

Don't use a structure. There is no structure in the C call. Use argtypes, but your last parameters were wrong:

from ctypes import *
lib = WinDLL(r"C:\FldSP970.dll")
lib.dFlComprOil.argtypes = c_int,c_double,c_double,c_double,c_double,c_double,c_double,c_double,c_bool,c_char_p,POINTER(c_int)
lib.dFlComprOil.restype = c_double
# Likely the last two parameters are output values, so allocate some amount of storage.
# Consult the function documentation...the size requirements aren't obvious.
errmsg = create_string_buffer(1024)  # equivalent to char[1024];
nerror = c_int()                     # A single C integer for output.
result = lib.dFlComprOil(0, 35, 0.65, 151.489, 861.066, 60, 100, 60,False,errmsg,byref(nerror))
answered on Stack Overflow Jan 3, 2021 by Mark Tolonen

User contributions licensed under CC BY-SA 3.0