2

I have been using Python to run a piece of software via a plug-in which is implemented as a DLL. This is provided through the following wrapper class:

from ctypes import *
import os

ANULL = -999999
gwbdll = None
if os.name == 'posix':
   gwbdll = cdll.LoadLibrary('libgwbplugin.so')
else:
   gwbdll = cdll.LoadLibrary('gwbplugin')

class GWBplugin:
   Name = "GWBplugin"
   def __init__(self):
      self.plugin = c_void_p (None)

   def initialize (self,app_name,file_name=None,cmds=None):
      return gwbdll.c_initialize(byref(self.plugin), c_char_p(app_name.encode()), file_name if file_name == None else c_char_p(file_name.encode()), cmds if cmds == None else c_char_p(cmds.encode()))

   def exec_cmd (self,uline):
      return gwbdll.c_exec_cmd(byref(self.plugin), c_char_p(uline.encode()))

   def results (self, value, units=None, ix=0, jy=0):
      type = c_void_p
      type_result = gwbdll.c_results(byref(self.plugin),c_void_p(None),c_char_p(value.encode()),c_char_p("DATATYPE".encode()),c_int(ix),c_int(jy))
      if type_result == 1:
         type = c_int
      elif type_result == 2:
         type = c_double
      elif type_result == 3:
         type = c_char_p
      else:
         return []
      
      count = gwbdll.c_results(byref(self.plugin),c_void_p(None),c_char_p(value.encode()),units if units == None else c_char_p(units.encode()),c_int(ix),c_int(jy))
      arr = (type*count)()
      gwbdll.c_results(byref(self.plugin),cast(arr,c_void_p),c_char_p(value.encode()),units if units == None else c_char_p(units.encode()),c_int(ix),c_int(jy))

      if type == c_char_p:
         arr = [x.decode('cp1252') for x in arr]

      return arr

   def destroy (self):
      gwbdll.c_destroy(byref(self.plugin))

   def __del__(self):
      gwbdll.c_destroy(byref(self.plugin))

I am running my program on a Jupyter notebook with Python 3.8.8 with code that looks like:

myPlugin = GWBplugin()
myPlugin.initialize("react", f_out, f_in_flagged)

where "react" is the name of the specific application I am using in this software, f_out looks like 'Output Files/pH 9/Reduced/0.0% Reduced/Output_6.txt', and f_in_flagged looks like "-i 'Input Files/pH 9/Reduced/0.0% Reduced/Input_6.rea'".

This is contained in a loop that runs through many different input files, and was running just fine until a few days ago when I generated more input files (contained within some new subdirectories) to run, and now it spits out the following error:

OSError                                   Traceback (most recent call last)
<ipython-input-6-fdf290a73be1> in <module>
     24 #         #Initialize: Application, Output file, Input file containing setup
---> 25         myPlugin.initialize("react", f_out, f_in_flagged)
     26         #Run
     27         myPlugin.exec_cmd("go")

C:\Program Files\Gwb\src\GWBplugin.py in initialize(self, app_name, file_name, cmds)
     15 
     16    def initialize (self,app_name,file_name=None,cmds=None):
---> 17       return gwbdll.c_initialize(byref(self.plugin), c_char_p(app_name.encode()), file_name if file_name == None else c_char_p(file_name.encode()), cmds if cmds == None else c_char_p(cmds.encode()))
     18 
     19    def exec_cmd (self,uline):

OSError: exception: access violation reading 0x0000000000000000

I am not really familiar with C or ctypes, but as far as I can tell this has something to do with the name of the input and output files I'm feeding it. I tried going back and running the files in the original directories that were working before (even tried completely uninstalling and reinstalling everything: the software, anaconda, and deleted all of the new files and directories) and am now getting the same error, so beyond that I am really at a loss as to what is going on. Any help is greatly appreciated!

rayc_126
  • 21
  • 1
  • 2
  • 1
    Most likely, it's a *dupe* of [\[SO\]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)](https://stackoverflow.com/questions/58610333/c-function-called-from-python-via-ctypes-returns-incorrect-value/58611011#58611011) (earch function's *argtypes*, *restype*). Very common mistake. If true, please mark this question as duplicate (or post a comment letting anyone who has the proper rights to do so). – CristiFati Sep 09 '21 at 01:11
  • I'm not sure that's the case - c_char_p(file_name.encode()) seems to work fine with f_out when I test it directly, and that also doesn't explain why my code that was working perfectly before has suddenly produced this error message after I pointed it to a new directory - even after deleting that new directory and pointing it back to the original. Maybe it's a memory issue? – rayc_126 Sep 09 '21 at 17:33
  • Set a breakpoint on GWBplugin.py:17 and see if any of the parameters are null pointers. We can't reproduce the issue with the code provided, so you'll have to debug. – Mark Tolonen Sep 09 '21 at 18:18
  • It looks like it was indeed a memory problem. I have no idea why that error specifically was the result, but it worked again when I moved to a machine with more available memory. – rayc_126 Sep 14 '21 at 20:11

0 Answers0