2014-10-12 74 views
0

我使用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']) 

它似乎沒有奏效。

我錯過了什麼?

回答

0

我是黑猩猩。 「垃圾郵件」需要被替換爲「簡單」,並且工作。

我會留下問題而不是刪除它,因爲它包含任何未來的PyCXX瀏覽器的有用踏腳石。

相關問題