我使用PyCXX圍繞嵌入式Python運行時創建C++包裝。使用PyCXX將模塊加載到嵌入式Python運行時
PyCXX似乎沒有一個可執行文件的例子,所以我試圖改編現有的示例代碼。
我可以得到Python解釋器輕鬆設置並運行:
extern "C" int Py_Main(int argc, PY_CHAR** argv);
int main(int argc, const char * argv[])
{
Py_Initialize();
PyRun_SimpleString("print('hello world') \n");
Py_Finalize();
}
這使一個全功能的Python提示符在我的Xcode調試/輸出窗口。
接下來,我公開了一個測試C++類,以便它在Python中變得可見。目前已經爲這個目的編寫的range
類:
extern "C" int Py_Main(int argc, PY_CHAR** argv);
int main(int argc, const char * argv[])
{
Py_Initialize();
range::init_type();
//test_extension_object(); <-- test-suite for 'range'
Py_Main(argc, (PY_CHAR**)argv); // wrong but works(!)
/*
This will launch a Python prompt in Xcode's output window
You can type:
>>> x = range(1,20,3)
>>> i = [a for a in x]
>>> i
[1, 4, 7, 10, 13, 16, 19]
>>> quit()
Program ended with exit code: 0
*/
Py_Finalize();
}
好,使作品也。
但現在我試圖加載一個模塊。
有一個稱爲「simple.cxx」一個簡單的演示模塊,它包含:
extern "C" EXPORT_SYMBOL PyObject *PyInit_simple()
{
static simple_module* simple = new simple_module;
return simple->module().ptr();
}
而且simple_module
類從PyCXX的ExtensionModule
類,它從ExtensionModuleBase
類派生,它具有初始化器派生:
void ExtensionModuleBase::initialize(const char *module_doc)
{
memset(&m_module_def, 0, sizeof(m_module_def));
m_module_def.m_name = const_cast<char *>(m_module_name.c_str());
m_module_def.m_doc = const_cast<char *>(module_doc);
m_module_def.m_methods = m_method_table.table();
// where does module_ptr get passed in?
m_module = PyModule_Create(&m_module_def);
}
如果我理解正確,其用途是將這個.cxx編譯成一個庫(OS X上的.so),並將它放在Python的搜索路徑的某處。
但它應該有可能得到這個工作,而不必編譯一個單獨的庫。這是我想要做的。
extern "C"
{
int Py_Main(int argc, PY_CHAR** argv);
PyObject *PyInit_example();
}
int main(int argc, const char * argv[])
{
PyImport_AppendInittab("spam", &PyInit_example);
Py_Initialize();
Py_Main(argc, (PY_CHAR**)argv); // wrong but works(!)
Py_Finalize();
}
我在這裏使用的文檔:https://docs.python.org/3.4/extending/embedding.html它告訴我使用PyImport_AppendInittab
。
現在我應該能夠從提示中看到這個模塊。它被稱爲simple
。
>>> import simple
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'simple'
>>> import sys
>>> sys.modules.keys()
dict_keys(['_weakrefset', 'copyreg', 'posix', '_io', 'encodings.aliases', '__main__', '_frozen_importlib', '_sysconfigdata', 'sys', 'encodings.utf_8', '_osx_support', 'marshal', 'builtins', 'encodings.ascii', 'abc', 'stat', '_weakref', 'atexit', '_bootlocale', 'rlcompleter', '_collections_abc', 're', 'readline', '_thread', 'zipimport', 'sre_constants', '_sitebuiltins', 'encodings.latin_1', '_sre', 'codecs', '_codecs', 'sysconfig', '_locale', 'posixpath', '_stat', 'encodings', 'genericpath', 'os.path', 'site', 'sitecustomize', 'sre_parse', 'io', 'os', 'errno', '_warnings', 'signal', 'sre_compile', '_imp'])
它似乎沒有奏效。
我錯過了什麼?