Call a python method from C/C++, and fail in access violation exception

0

We wanna call a c/c++ extension in python, and in the extension we need to callback one function in the python script.

Here is the python code

# -*- coding: UTF-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8') 
import ctypes

class MyClass:
    def func(self):
        print "func"
        open("out.txt","w").write("func")
        print "func2"
        return


mDll = ctypes.CDLL("xx.dll", ctypes.RTLD_GLOBAL)
c = MyClass()
# c.func() is what we wanna run below
mDll.callFunc.argtypes = [ctypes.py_object]
mDll.callFunc(c)

Below is the c source for xx.dll, built by VS 2008:

__declspec(dllexport) int callFunc(PyObject* self){
    printf("callFunc\n");
    //PyObject* ret = PyObject_CallMethod(self, "func", NULL);

    PyObject* ret2 = PyObject_CallFunctionObjArgs(PyObject_GetAttrString(self, (char*)"func") , self, NULL);

    printf("callFunc2\n");

    return 0;
}

We have tried two methods (PyObject_CallFunctionObjArgs / PyObject_CallMethod),and neither of the two methods failed in the calling. The results shows:

Traceback (most recent call last):
  File "test\tCall.py", line 19, in <module>
    mDll.callFunc(c)
WindowsError: exception: access violation writing 0x0000000C

How could we call the MyClass.func ?

python
python-c-api
asked on Stack Overflow Apr 7, 2018 by Azure

1 Answer

1

ctypes releases the GIL before calling anything loaded with CDLL. You need to explicitly hold it, or use ctypes.PyDLL, or actually, it's probably best to just write a normal extension module instead of loading DLLs manually.

Also, manage your references, and don't pass self to the func method; that happens implicitly.

(I don't know if those are all of the problems, but those are the ones I noticed.)


User contributions licensed under CC BY-SA 3.0