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?

4 Answers 4

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()
Sign up to request clarification or add additional context in comments.

5 Comments

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?
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.
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
@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.
Thank you. Now if only boost gave a simple EXAMPLE in their documentation of how you do this... At least we have Stack Overflow.
4

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

1 Comment

If you have a boost::python::object, you can just use its operator() to call it.
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.

2 Comments

Boost python documentation is largely out of date and extremely bad even where it is up-to-date.
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".
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.