embed python in c++, crashes on "import shutil"
<p>I have a complete example on embedding python in c++ below.  I compile/link it on Linux against Python 2.7.</p>

<p>It takes one parameter (a filename) which is then loaded and executed.</p>

<p>All this basically works but if in the code there is:
import shutils</p>

<p>Then executing the code fails with a bus error.</p>

<p>It seems this is related to the underlying "import collections".</p>

<p>The code that I load runs normally when I just execute it as a python script.</p>

<p>Has anybody got a hint why the code crashes?  The code is made up from several examples and should just normally work.</p>

<p>Here is the C++ code:</p>

<pre><code>#include "Python.h" // must be first
#include "structmember.h"

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define QWE printf("%s %i\n", __FUNCTION__, __LINE__);


#define LIBPY_NAMESPACE "app"
#define LIBPY_TYPE  "App"
#define LIBPY_FQTYPE  LIBPY_NAMESPACE "." LIBPY_TYPE


static PyObject* globals;
static PyObject* locals;

static PyObject* mod;
static PyObject* app_class;

static PyObject* AppError;


typedef struct {
  PyObject_HEAD

} AppObject;


static PyObject* app_func1(AppObject* self, PyObject* args)
{
  PyObject* ret;
  int p1, p2;

  if(PyArg_ParseTuple(args, "dd", &amp;p1, &amp;p2)) {
    //    try {

      ret = Py_BuildValue("(i,i,i,i)", 13, 17, 19, 11 + p1 + p2);

      return ret;
      /*
    }
    catch(RiException&amp; e) {
      PyErr_SetString(RiError, e.what());
    }
      */
  }

  return NULL;
}


static PyObject* app_func2(AppObject* self, PyObject* args)
{
  PyObject* ret;

  ret = Py_BuildValue("(i,i,i,i)", 4, 13, 17, 19);

  return ret;
}


static PyObject* app_filename(AppObject* self, PyObject* args)
{
  PyObject* ret;
  const char* c = "a filename";

  //  ret = Py_BuildValue("(i,i,i,i)", 4, 13, 17, 19);
  ret = Py_BuildValue("s", c);

  return ret;
}


static PyMethodDef app_global_methods[] = {
  {"filename", (PyCFunction)app_filename, METH_VARARGS, "an example for a global function"},
  // get file name

  {NULL, NULL, 0, NULL}
};


static PyMethodDef app_methods[] = {
  {"func1", (PyCFunction)app_func1, METH_VARARGS, "a test function 1."},
  {"func2", (PyCFunction)app_func2, METH_NOARGS, "a test function 2."}
};


static PyMemberDef app_members[] = {
  //  {"width", T_INT, offsetof(RiMem, w), 0, ""},
  {NULL}
};


static PyObject* app_repr(PyObject* par) {
  AppObject* self = (AppObject*)par;

  return PyString_FromFormat("&lt;%s  %i&gt;", "wx Application", 4);
}


static PyObject* app_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
  AppObject *self;

  QWE;
  self = (AppObject *)type-&gt;tp_alloc(type, 0);
  if(self != NULL) {
    //    self-&gt;app = NULL;
  }

  return (PyObject *)self;
}


static int app_init(AppObject* self, PyObject* args, PyObject* kwds) {
  //  self-&gt;app = m_app;

  QWE;
  PyErr_Clear();

  //  PyErr_SetString(RiError, "some error happened");

  return 0;
}


static void app_dealloc(AppObject* self) {
  QWE;
  /*  if(self-&gt;app != NULL) {
    // delete the app

    self-&gt;app = NULL;
    } */

  self-&gt;ob_type-&gt;tp_free((PyObject*)self);
}


static PyTypeObject AppType = {
  PyObject_HEAD_INIT(NULL)

  0, /*ob_size*/
  LIBPY_FQTYPE, /*tp_name*/
  sizeof(AppObject), /*tp_basicsize*/
  0, /*tp_itemsize*/
  (destructor)app_dealloc, /*tp_dealloc*/
  0, /*tp_print*/
  0, /*tp_getattr*/
  0, /*tp_setattr*/
  0, /*tp_compare*/
  app_repr, /*tp_repr*/
  0, /*tp_as_number*/
  0, /*tp_as_sequence*/
  0, /*tp_as_mapping*/
  0, /*tp_hash */
  0, /*tp_call*/
  0, /*tp_str*/
  0, /*tp_getattro*/
  0, /*tp_setattro*/
  0, /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "An example application", /* tp_doc */
  0, /* tp_traverse */
  0, /* tp_clear */
  0, /* tp_richcompare */
  0, /* tp_weaklistoffset */
  0, /* tp_iter */
  0, /* tp_iternext */
  app_methods, /* tp_methods */
  app_members, /* tp_members */
  0, /* tp_getset */
  0, /* tp_base */
  0, /* tp_dict */
  0, /* tp_descr_get */
  0, /* tp_descr_set */
  0, /* tp_dictoffset */
  (initproc)app_init, /* tp_init */
  0, /* tp_alloc */
  app_new, /* tp_new */
};


void init_py(void) {
  Py_SetProgramName("qwe");
  Py_Initialize();

#if 0
  globals = PyDict_New();
  PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
#else
  globals = PyModule_GetDict(PyImport_AddModule("__main__"));
#endif

  printf("globals %p\n", globals);

  /*  if (PyType_Ready(&amp;AppType) &lt; 0) {
    return;
    } */

  mod = Py_InitModule3(LIBPY_NAMESPACE, app_global_methods, "an example app module");
  locals = PyModule_GetDict(mod);

  Py_INCREF(&amp;AppType);
  PyModule_AddObject(mod, LIBPY_TYPE, (PyObject *)&amp;AppType);

  PyModule_AddIntConstant(mod, "CONST1", 11);
  PyModule_AddIntConstant(mod, "CONST2", 13);

  app_class = PyObject_GetAttrString(mod, LIBPY_TYPE);

  AppError = PyErr_NewException((char*)LIBPY_FQTYPE "Error", NULL, NULL);
  Py_INCREF(AppError);
  PyModule_AddObject(mod, LIBPY_TYPE "Error", AppError);

  //  PyRun_SimpleString("from time import time,ctime\nprint 'Today is',ctime(time())\n");
  //  Py_Finalize();

}

char* load_file(const char* fname) {
  FILE* fd;
  long pos;
  size_t len;
  char* data;

  fd = fopen(fname, "rb");
  assert(fd != NULL);
  fseek(fd, 0, SEEK_END);
  pos = ftell(fd);
  fseek(fd, 0, SEEK_SET);

  data = (char*)malloc(pos+1);
  assert(data != NULL);

  len = fread(data, 1, pos, fd);
  assert(len == (size_t)pos);

  data[pos] = 0;

  return data;
}


int main(int argc, char** argv) {
  char* c;
  PyObject* val;

  printf("Hi there\n");

  if(argc != 2) {
    printf("need one parameter\n");
    exit(-1);
  }

  init_py();

  c = load_file(argv[1]);
  printf("script &lt;%s&gt;\n", c);

  QWE;

#if 1
  PyRun_SimpleString(c);
#else
  val = PyRun_String(c, Py_file_input, globals, locals);
  QWE;
  if(val == NULL) {
    PyErr_Print();
  }
  else {
    Py_DECREF(val);
  }
#endif

  QWE;

  return 0;
}
</code></pre>

<p>A Python script that fails is:</p>

<pre><code>#! /usr/bin/python
#coding: latin-1

#from app import *

import os
import shutil

import sys
import stat
import fnmatch
import collections


#print filename()
</code></pre>

<p>So when compiling the code and then calling it with a parameter (file containing the python code) it results in a bus error.</p>

<p>Compiling the code above as C or C++ gives the same result.  I'm interested in getting it to work with C++.</p>

<p>Can anybody at least reproduce the problem?</p>

<p>May be it is related to GIL problem, try this: <a href="https://docs.python.org/3/c-api/init.html#non-python-created-threads" rel="nofollow">https://docs.python.org/3/c-api/init.html#non-python-created-threads</a></p>

python c++ python-2.7 embed