How to use boost::python::dict or tuple in main function?
Asked Answered
L

1

5

When I use boost::python::tuple or boost::python::dict in main function, the program crash!

#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
#include <iostream>
#include <boost/python/tuple.hpp>
#include <boost/python/dict.hpp>

//using namespace std;
using namespace boost::python;

int main()
{
    //tuple x;
    //x = make_tuple(object(0),object(1));
    dict x;
    x["123"] = 3;
    return 0;
}

But when I use them in .dll, it is ok, what's wrong?

Limnology answered 25/7, 2017 at 14:43 Comment(0)
K
6

It's necessary to call Py_Initialize() to initialize the interpreter before the use of any python object:

#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
#include <iostream>
#include <boost/python/tuple.hpp>
#include <boost/python/dict.hpp>

//using namespace std;
using namespace boost::python;

int main()
{
    Py_Initialize();
    dict x;
    x["123"] = 3;
    return 0;
}

Boost Python offers a lot of functionalities to interface C++ with Python, but also some funcionalities to create C extensions in a higher level using C++. The code above is perfectly correspondent to the code bellow:

#include <Python.h>
#include <dictobject.h>

int main(int argc, char *argv[])
{
    Py_Initialize();
    PyObject *d = PyDict_New();
    PyDict_SetItemString(d, "123", PyLong_FromLong(3));
    return 0;
}

Inside PyDict_SetItemString there is a call to PyUnicode_InternInPlace that basically tries to use a string that already exists, otherwise it creates a new one (remember that python strings are immutable). The segfault (when Py_Initilize is not called) occurs inside this function, because Python needs to query it's runtime environment to check for the string, but once the envirnment is not loaded, it crashes.

It's not necessary to explicit call Py_Initilize when creating a .dll, because it is imported inside the interpreter that already called it during its initialization.

Konstanz answered 25/7, 2017 at 20:13 Comment(5)
But when I use in .dll, I don't use Py_Initialize(), it works well. Could you tell me the details?Limnology
I'm not sure, I think it's because when you import the .dll, python interpreter is already loaded (somebody already called Py_Initialize()) so you don't need to load it again.Pea
@Limnology I've just update the answer providing more info about it.Pea
Python.h, dictobject.h, PyObject belong to boost.Python? I don't see that code. What does Py_Initilize do? To change C environment to python?Limnology
No, these are the header files from CPython implementation. Py_Initialize() is very well documented in the internet, stop being lazy!Pea

© 2022 - 2024 — McMap. All rights reserved.