1

I have simple example, where I'm trying to transfer control into python code. Class A have field myFunction that is python method I want to transfer the control.

cpp code:

class A {
private:
    PyTypeObject* myFunction;
    bool flag = true;
public:
    A() {
        Py_Initialize();
    };

    void setFunc(PyTypeObject* func) {
        myFunction = func;
    }

    void runFunc(double a) {
        std::cout << PyType_Check(myFunction);
        // I want to call python method here
    }

    void loop() {
        while (flag) {
            runFunc(12);
            sleep(2);
        }
    }
};

extern "C" { // this is interface for calling cpp methods with ctypes
    A* new_a() {
        return new A();
    }

    void a_setFunc(A* a, PyTypeObject* func) {
        return a->setFunc(func);
    }

    void loop(A* a) {
        return a->loop();
    }
}

python code:

from ctypes import cdll

libA = cdll.LoadLibrary('build/Debug/libpop.so')

def foo():
    print 'a'

class A():
    def listener(self, a):
        print str(a + 2)

    def __init__(self):
        self.object = libA.new_a()

    def setFunc(self):
        return libA.a_setFunc(self.object, self.listener) #here is an error

    def run(self):
        return libA.loop(self.object)

test = A()
test.setFunc()
test.run()

when I'm running py code, I have following error:

ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to convert parameter 2

How can I resolve this problem?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • You should use `libA = ctypes.PyDLL('libpop.so')`. PyDLL doesn't release the global interpreter lock (GIL), unlike CDLL. Holding the GIL is required to use the C Python API. – Mark Tolonen Jul 09 '19 at 06:39
  • You can also do callbacks with `ctypes` with a C++ DLL without using the Python API. See [this answer](https://stackoverflow.com/a/53819770/235698) for an example. – Mark Tolonen Jul 09 '19 at 06:40

1 Answers1

1

In Python C API, PyTypeObject* is a pointer to a struct describing a Python type. I think you're looking for PyObject* which is a pointer to a Python object, which is what it looks like you're aiming for.

Here's another question with a similar resolution: how to deal with the PyObject* from C++ in Python

Community
  • 1
  • 1
mobiusklein
  • 1,403
  • 9
  • 12