2016-08-31 7 views
2

埋め込みPython 3インタプリタを作成し、PythonスクリプトにC Python API経由で作成したモジュールを読み込ませたいと考えています。埋め込みのPythonでパッケージ構造をプログラムで定義する3

"トップレベル"モジュールを作成するのに問題はありませんが、今ではパッケージでモジュールを構成したいと思います...しかし失敗しました。

#include <Python.h> 

//// Definition of 'emb.sub' module 
static PyObject* emb_sub_foo(PyObject *self, PyObject *args) 
{ 
    char const* n = "I am sub foo"; 
    return Py_BuildValue("s", n); 
} 
static PyMethodDef EmbSubMethods[] = { 
    {"foo", emb_sub_foo, METH_VARARGS, "Returns sub foo"}, 
    {NULL, NULL, 0, NULL} 
}; 
static PyModuleDef EmbSubModule = { 
    PyModuleDef_HEAD_INIT, "emb.sub", NULL, -1, EmbSubMethods, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb_sub(void) 
{ 
    return PyModule_Create(&EmbSubModule); 
} 

//// Embedded Python 
int main() 
{ 
    PyImport_AppendInittab("emb.emb", &PyInit_emb_sub); 
    Py_Initialize(); 

    PyRun_SimpleString("import emb.sub\n"); 

    Py_Finalize(); 
    return 0; 
} 

私がプログラムを実行すると、私が手::

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
ImportError: No module named 'emb' 

だから私は空のEMBモジュールを作成し、私は次のようにその__path__を設定ここで

は私の現在の(簡単な)コードですこの:

#include <Python.h> 

//// Definition of 'emb' module 
static PyModuleDef EmbModule = { 
    PyModuleDef_HEAD_INIT, "emb", NULL, -1, NULL, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb(void) 
{ 
    PyObject *mod = PyModule_Create(&EmbModule); 
    PyModule_AddObject(mod, "__path__", Py_BuildValue("()")); 

    return mod; 
} 

//// Definition of 'emb.sub' module 
static PyObject* emb_sub_foo(PyObject *self, PyObject *args) 
{ 
    char const* n = "I am sub foo"; 
    return Py_BuildValue("s", n); 
} 
static PyMethodDef EmbSubMethods[] = { 
    {"foo", emb_sub_foo, METH_VARARGS, "Returns sub foo"}, 
    {NULL, NULL, 0, NULL} 
}; 
static PyModuleDef EmbSubModule = { 
    PyModuleDef_HEAD_INIT, "emb.sub", NULL, -1, EmbSubMethods, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb_sub(void) 
{ 
    return PyModule_Create(&EmbSubModule); 
} 

//// Embedded Python 
int main() 
{ 
    PyImport_AppendInittab("emb", &PyInit_emb); 
    PyImport_AppendInittab("emb.sub", &PyInit_emb_sub); 
    Py_Initialize(); 

    PyRun_SimpleString("import emb.sub\n"); 

    Py_Finalize(); 
    return 0; 
} 

そして今、私はこのエラーを取得する:

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
ImportError: No module named 'emb.sub' 

埋め込みPythonでパッケージとモジュールの階層を作成することは可能でしょうか?

ありがとうございます!

+0

あなたは今まで見つけますか溶液? – Ha11owed

+0

@ Ha11owed最後に私はパッケージを使いませんでしたが、回答を受け入れました。 – merovingien

答えて

1

デフォルトの組み込みモジュールの処理は、パッケージ+モジュール名と一致しないことが分かります。これは、()だけPy_Initialize後にこれを実行し、ないカスタムインポートフックを追加することで回避することができます。

PyRun_SimpleString(
    "import importlib.abc\n" \ 
    "import importlib.machinery\n" \ 
    "import sys\n" \ 
    "\n" \ 
    "\n" \ 
    "class Finder(importlib.abc.MetaPathFinder):\n" \ 
    " def find_spec(self, fullname, path, target=None):\n" \ 
    "  if fullname in sys.builtin_module_names:\n" \ 
    "   return importlib.machinery.ModuleSpec(\n" \ 
    "    fullname,\n" \ 
    "    importlib.machinery.BuiltinImporter,\n" \ 
    "   )\n" \ 
    "\n" \ 
    "\n" \ 
    "sys.meta_path.append(Finder())\n" \ 
); 

私は成功を収めて、あなたの完全なコードでこれを試してみました:

#include <Python.h> 

//// Definition of 'emb' module 
static PyModuleDef EmbModule = { 
    PyModuleDef_HEAD_INIT, "emb", NULL, -1, NULL, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb(void) 
{ 
    PyObject *mod = PyModule_Create(&EmbModule); 
    PyModule_AddObject(mod, "__path__", Py_BuildValue("()")); 

    return mod; 
} 

//// Definition of 'emb.sub' module 
static PyObject* emb_sub_foo(PyObject *self, PyObject *args) 
{ 
    char const* n = "I am sub foo"; 
    return Py_BuildValue("s", n); 
} 
static PyMethodDef EmbSubMethods[] = { 
    {"foo", emb_sub_foo, METH_VARARGS, "Returns sub foo"}, 
    {NULL, NULL, 0, NULL} 
}; 
static PyModuleDef EmbSubModule = { 
    PyModuleDef_HEAD_INIT, "emb.sub", NULL, -1, EmbSubMethods, 
    NULL, NULL, NULL, NULL 
}; 
static PyObject* PyInit_emb_sub(void) 
{ 
    return PyModule_Create(&EmbSubModule); 
} 

//// Embedded Python 
int main() 
{ 
    PyImport_AppendInittab("emb", &PyInit_emb); 
    PyImport_AppendInittab("emb.sub", &PyInit_emb_sub); 
    Py_Initialize(); 

    PyRun_SimpleString(
     "import importlib.abc\n" \ 
     "import importlib.machinery\n" \ 
     "import sys\n" \ 
     "\n" \ 
     "\n" \ 
     "class Finder(importlib.abc.MetaPathFinder):\n" \ 
     " def find_spec(self, fullname, path, target=None):\n" \ 
     "  if fullname in sys.builtin_module_names:\n" \ 
     "   return importlib.machinery.ModuleSpec(\n" \ 
     "    fullname,\n" \ 
     "    importlib.machinery.BuiltinImporter,\n" \ 
     "   )\n" \ 
     "\n" \ 
     "\n" \ 
     "sys.meta_path.append(Finder())\n" \ 
    ); 

    PyRun_SimpleString("import emb.sub\n"); 
    PyRun_SimpleString("print(emb.sub.foo())\n"); 

    Py_Finalize(); 
    return 0; 
} 
+0

この回答は受け入れられるべきです。 – poukill

関連する問題