首页 > 解决方案 > 来自 C++ 的 Python,为什么模块导入需要 PySys_SetArgv 才能工作

问题描述

考虑以下从 C++ 运行嵌入式 Python 脚本的代码。它创建一个嵌入式 Python 模块,然后运行一个导入第二个脚本的脚本。

#include <Python.h>

#include <iostream>
#include <fstream>

PyObject * mymodule_meth_test(PyObject * self) {
    std::cout << "Hello World!" << std::endl;

    Py_RETURN_NONE;
}

PyMethodDef module_methods[] = {
    {"test", (PyCFunction)mymodule_meth_test, METH_NOARGS, NULL},
    {},
};

PyModuleDef module_def = {PyModuleDef_HEAD_INIT, "mymodule", NULL, -1, module_methods};

extern "C" PyObject * PyInit_mymodule() {
    PyObject * module = PyModule_Create(&module_def);
    return module;
}

void runScript( const std::string& script, bool setArgv )
{
    Py_SetPythonHome( L"C:\\dev\\vobs_sde\\sde\\3rdparty\\tools_ext\\python\\Python38" );

    PyImport_AppendInittab("mymodule", &PyInit_mymodule);

    // Initialize the Python Interpreter
    Py_Initialize();

    wchar_t** _argv = (wchar_t**) PyMem_Malloc(0);
    if ( setArgv )
        PySys_SetArgv(0, _argv);

    FILE* file = NULL;
    fopen_s(&file,script.c_str(),"r");
    if ( file )
    {
        PyRun_SimpleFile(file, script.c_str());
        fclose(file);
    }

    PyMem_Free( _argv );

    Py_Finalize();
}

int main( int argc, char* argv[] )
{
    std::fstream file1;
    file1.open( "mainfile.py", std::ios_base::out );
    file1 << "import mymodule" << std::endl;
    file1 << "mymodule.test()" << std::endl;
    file1.close();

    runScript( "mainfile.py", false );

    std::fstream file2;
    file2.open( "importing.py", std::ios_base::out );
    file2 << "import mainfile" << std::endl;
    file2.close();

    runScript( "importing.py", false );
    runScript( "importing.py", true );

    return 0;
}

输出它:

Hello World!
Traceback (most recent call last):
  File "importing.py", line 1, in <module>
    import mainfile
ModuleNotFoundError: No module named 'mainfile'
Hello World!

它表明当未调用时,从PySys_SetArgv导入失败。为什么?这是 Python 错误还是必须调用此函数?mainfile.pyimporting.py

标签: pythonc++python-embedding

解决方案


推荐阅读