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

eryk sun eryksun at gmail.com
Mon Jan 22 17:41:38 EST 2018


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