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