私は以下のC++でpythonを埋め込んだ完全な例を持っています。 Linux上でPython 2.7に対してコンパイル/リンクします。PythonをC++に埋め込み、 "import shutil"でクラッシュする
1つのパラメータ(ファイル名)が読み込まれ、実行されます。
すべてこれは基本的に動作しますが、コード内に存在する場合: インポートshutils
は、その後のコードを実行するとバスエラーで失敗します。
これは、基本的な「インポートコレクション」に関連しているようです。
私がロードするコードは、Pythonスクリプトとして実行すると正常に実行されます。
コードがクラッシュする理由を誰かが知っていますか?コードはいくつかの例で構成されており、通常は正常に動作するはずです。ここで
は、C++コードです:失敗した
#include "Python.h" // must be first
#include "structmember.h"
#include <stdio.h>
#include <stdlib.h>
#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", &p1, &p2)) {
// try {
ret = Py_BuildValue("(i,i,i,i)", 13, 17, 19, 11 + p1 + p2);
return ret;
/*
}
catch(RiException& 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("<%s %i>", "wx Application", 4);
}
static PyObject* app_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
AppObject *self;
QWE;
self = (AppObject *)type->tp_alloc(type, 0);
if(self != NULL) {
// self->app = NULL;
}
return (PyObject *)self;
}
static int app_init(AppObject* self, PyObject* args, PyObject* kwds) {
// self->app = m_app;
QWE;
PyErr_Clear();
// PyErr_SetString(RiError, "some error happened");
return 0;
}
static void app_dealloc(AppObject* self) {
QWE;
/* if(self->app != NULL) {
// delete the app
self->app = NULL;
} */
self->ob_type->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(&AppType) < 0) {
return;
} */
mod = Py_InitModule3(LIBPY_NAMESPACE, app_global_methods, "an example app module");
locals = PyModule_GetDict(mod);
Py_INCREF(&AppType);
PyModule_AddObject(mod, LIBPY_TYPE, (PyObject *)&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 <%s>\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;
}
A Pythonスクリプトは次のとおりです。
#! /usr/bin/python
#coding: latin-1
#from app import *
import os
import shutil
import sys
import stat
import fnmatch
import collections
#print filename()
だから、コードをコンパイルして、パラメータ(Pythonのコードを含むファイル)とそれを呼び出すときバスエラーが発生します。
上記のコードをCまたはC++でコンパイルすると同じ結果が得られます。私はそれをC++で動かすことに興味があります。
誰でも少なくとも問題を再現できますか?
CまたはC++?一つを選ぶ。 – Biffen
テキストの見出しと最初の文で説明したように、C++です。それとも私はあなたの意見を誤解しましたか? –
だから、「* Cコードは?」の後にCコードが続きますか? – Biffen