Help: 64bit python call c and got OSError: exception: access violation writing 0xFFFFFFFF99222A60

Jason Qian jqian at tibco.com
Mon Jan 22 20:50:11 EST 2018


Thanks for the help,

Jason

On Mon, Jan 22, 2018 at 5:41 PM, eryk sun <eryksun at gmail.com> wrote:

> On Mon, Jan 22, 2018 at 9:00 PM, Jason Qian via Python-list
> <python-list at python.org> wrote:
> >
> > I am using ctypes on Windows to interface with a dll  and it works fine
> > on Linux and windows 32-bit python.  But, when using 64-bit python, we
> got
> > error "exception: access violation writing 0xFFFFFFFF99222A60".
> >
> > from ctypes import *
>
> Try to avoid * imports if it's a public module.
>
> > lib = cdll.LoadLibrary('xxxxxxx.dll')
>
> Just use CDLL directly. cdll.LoadLibrary is pointless, and
> `cdll.xxxxxxx` is problematic in some cases because it caches CDLL
> instances, which cache function pointers. Also, the ".dll" filename
> extension isn't required in Windows.
>
> > lib.createService.argtypes=[c_int,ctypes.c_char_p]
> > lib.createService.restype=ctypes.c_int
> >
> > class myDriver(object):
> > def init(self):
> > self.obj = lib.loadInstance()
>
> Since you didn't set loadInstance.restype, the result gets truncated
> as a C int, the default result type.
>
> I recommend defining an opaque ctypes struct (i.e. no defined fields)
> for the C++ class. This provides type safety. Staying strict and
> literal on types is more work than using a `void *` everywhere, but it
> pays off in terms of easier debugging and more resilient code. A
> simple example is that ctypes returns a `void *` result (or gets a
> struct field or array item) as a Python integer. Then for any FFI call
> that you may have forgotten to define argtypes, ctypes will default to
> truncating this integer value as a C int. At best that causes an
> immediate crash. At worst it's a subtle bug that corrupts data.
>
> Here's an example implementation with an opaque struct:
>
>     import ctypes
>
>     lib = ctypes.CDLL('xxxxxxx')
>
>     class myPythonAPI(ctypes.Structure):
>         pass
>
>     PmyPythonAPI = ctypes.POINTER(myPythonAPI)
>
>     lib.loadInstance.restype = PmyPythonAPI
>     lib.loadInstance.argtypes = ()
>
>     lib.createService.restype = ctypes.c_int
>     lib.createService.argtypes = (PmyPythonAPI, ctypes.c_char_p)
>
>     class myDriver(object):
>
>         def init(self):
>             self.obj = lib.loadInstance()
>
>         def create_services(self, servicename):
>             return lib.createService(self.obj, servicename)
>



More information about the Python-list mailing list