ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The solution comes in three parts:

1) As per Linas's answer, you need to save the thread state with PyEval_SaveThread()

2) You need to call rospy.spin() before shutting down to give time for all the rospy threads to terminate. If a rospy thread is active when you call Py_Finalize(), you may get a crash.

3) You need to restore the main thread state as saved in 1) above via a call to PyThreadState_Swap before calling Py_Finalize().

The following is a working version of the above sample:

#include <Python.h>

int main(int argc, char* argv[])
{
    Py_InitializeEx(0);
    PyEval_InitThreads();

    static const char *argv0 = "test";
    PySys_SetArgv(1, (char **) &argv0);

    // Call this instead of PyEval_ReleaseLock()
    PyThreadState* thread_state = PyEval_SaveThread() ;

    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    PyRun_SimpleString("import rospy");
    printf ("import rospy - successful\n");

    PyRun_SimpleString("rospy.init_node('OpenCog_Eva')");

    // Make sure the thread doesn't exit before rospy is shutdown.
    PyRun_SimpleString("rospy.spin()");
    PyGILState_Release(gstate);

    // Restore the main thread saved above.
    PyThreadState_Swap(thread_state);

    Py_Finalize();
    printf ("finished\n");
    return 0;
}