TransWikia.com

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

Stack Overflow Asked by OliverX on January 21, 2021

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.

One Answer

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))

Correct answer by Mark Tolonen on January 21, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP