2014-10-12 4 views
0

PyCXX을 사용하여 임베디드 Python 런타임 주위에 C++ 래퍼를 만듭니다.PyCXX를 사용하여 임베디드 Python 런타임에 모듈로드

PyCXX는 실행 파일의 예제가없는 것처럼 보이므로 기존 예제 코드를 수정하려고합니다.

나는 파이썬 인터프리터까지 쉽게 실행 얻을 수 있습니다 : 내 엑스 코드 디버그/출력 창에 완전한 기능의 파이썬 프롬프트를두고

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 내에서 볼 수 있도록 테스트 C++ 클래스를 노출합니다.

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(); 

} 

좋아, 그래서도 작동이 목적을 위해 작성되었습니다 range 클래스가있다.

하지만 이제 모듈을로드하려고합니다.

포함 "simple.cxx"라는 간단한 데모 모듈이있다 :

extern "C" EXPORT_SYMBOL PyObject *PyInit_simple() 
{ 
    static simple_module* simple = new simple_module; 
    return simple->module().ptr(); 
} 

그리고 simple_module 클래스는 initialiser이있는 ExtensionModuleBase 클래스에서 파생 PyCXX의 ExtensionModule 클래스에서 파생 :

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의 검색 경로 어딘가에 배치해야합니다.

하지만 별도의 라이브러리를 컴파일하지 않고도이 작업을 수행 할 수 있어야합니다. 이것이 내가하려는 일이다. https://docs.python.org/3.4/extending/embedding.htmlPyImport_AppendInittab를 사용하도록 지시합니다

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(); 
} 

여기 문서를 사용하고 있습니다.

이제이 모듈을 프롬프트에서 볼 수 있습니다. 그것은 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 탐색기에 유용한 스테핑 스톤이 포함되어 있으므로 질문을 삭제하지 않고 그대로 두겠습니다.