18

I am trying to achieve call Python functions from C++. I thought it could be achieved through function pointers, but it does not seem to be possible. I have been using boost.python to accomplish this.

Say there is a function defined in Python:

def callback(arg1, arg2):
    #do something
    return something

Now I need to pass this function to C++, so that it can be called from there. How do I write the code on C++ side using boost.python to achieve this?

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Amar
  • 393
  • 1
  • 5
  • 9

4 Answers4

15

If it might have any name:

Pass it to a function that takes a boost::python::object.

bp::object pycb; //global variable. could also store it in a map, etc
void register_callback(bp::object cb)
{
      pycb = cb;
}

If it is in a single known namespace with a consistent name:

bp::object pycb = bp::scope("namespace").attr("callback");

bp::object has operator() defined, so you call it just like any function

ret = pycb()
Neel Basu
  • 12,638
  • 12
  • 82
  • 146
Matthew Scouten
  • 15,303
  • 9
  • 33
  • 50
  • Thnks Matthew, I have an additional question. Here the python object is being called from the same thread. What if python object was global and was being called from a different thread? – Amar Dec 03 '10 at 03:24
  • That is possible, although somewhat beyond the scope of this question. I recommend investigating the C/Python API's PyGILState_* family of functions. Unlike Boost-Python, Python has very good docs. If you still need more help, ask another question. – Matthew Scouten Dec 03 '10 at 21:48
  • 2
    For Future viewers: Someone eventually asked that other question, and I answered it. Look over here: stackoverflow.com/questions/8009613/boost-python-not-supporting-parallelism/8011153#8011153 – Matthew Scouten Dec 06 '11 at 22:23
  • 1
    @MatthewScouten can you please give a simple working example of above topic so I can understand well, as I am very new to C++ and I know more about the Python. – lkkkk May 13 '14 at 04:54
  • Thank you. Now if only boost gave a simple EXAMPLE in their documentation of how you do this... At least we have Stack Overflow. – CashCow Dec 07 '16 at 08:55
4

Not a clue. But you can use PyObject_Call() to call it once you have the function object.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

I've not used it before, but the reference manual has a section called Calling Python Functions and Methods which seems to show how to do this.

Ken
  • 256
  • 1
  • 3
  • 2
    Boost python documentation is largely out of date and extremely bad even where it is up-to-date. – Matthew Scouten Dec 02 '10 at 16:57
  • That page does not show you a Python function. It just shows you how to call one with an already bound object. Not exactly a "simple example". – CashCow Dec 07 '16 at 09:07
1

I used PyRun_SimpleString("myFunction()") as quick hack, as my function's name was known, took no args and lived in the __main__ namespace. Note you additionally need to get lock GIL if you are multi-threaded.

eudoxos
  • 18,545
  • 10
  • 61
  • 110