Загрузите модуль во встроенную среду исполнения Python, используя PyCXX

я использую PyCXX создать оболочку C ++ вокруг встроенной среды выполнения 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. Eсть 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 в библиотеку (.so в OS X) и поместить его где-нибудь в пути поиска 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.

0

Другие решения


По вопросам рекламы [email protected]