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 ?

Azure
  • 154
  • 1
  • 10
  • You must have a (C-level) stack trace? If not, attach a debugger to Python before calling this function. – abarnert Apr 07 '18 at 02:29
  • Meanwhile, is the crash happening in `PyObject_GetAttrString`, or is it returning NULL and you're ignoring it, or is it returning something that looks reasonable but then `PyObject_CallFunctionObjArgs` crashes? – abarnert Apr 07 '18 at 02:30
  • Also, what version of Python are you using, and is it from the standard python.org installer or elsewhere? (Was it built with VS2008, or a different compiler?) – abarnert Apr 07 '18 at 02:31
  • PyObject_GetAttrString calling is successful, I have used PyObject_Repr to print the results. The python 2.7 is built using VS2008, I am sure that and has used it to call c/c++ extension before. – Azure Apr 07 '18 at 03:30
  • I have tested using many trials, it's been proved the program stopped in the calling of PyObject_CallMethod/PyObject_CallFunctionObjArgs , the "callFunc" is shown correctly ,while the clause in the func is not running even there is only "return" clause. – Azure Apr 07 '18 at 03:34

1 Answers1

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.)

user2357112
  • 260,549
  • 28
  • 431
  • 505