无法从 Python C API 中内置的模块调用方法

Posted

技术标签:

【中文标题】无法从 Python C API 中内置的模块调用方法【英文标题】:Can't call a method from a module built in Python C API 【发布时间】:2019-04-08 13:50:46 【问题描述】:

我正在尝试使用 Python C API 在 C++ 中构建一个 python 模块,代码如下:

#include "Python.h"
#include <iostream>

class MyClass 
public:
    MyClass() ;

    static MyClass& getInstance() 
        static MyClass instance;
        return instance;
    

    void tester() 
        std::cout << "testing..." << std::endl;
    

    static void runTesterFunc(PyObject*, PyObject*) 
        static MyClass& myObj = MyClass::getInstance();
        myObj.tester();
    

    static PyObject* getModule()  
        Py_SetPythonHome(L"C:\\Python36");
        Py_SetProgramName(L"my_program");

        PyMethodDef pyModuleMethods[] = 
             "runTester", (PyCFunction)runTesterFunc, METH_VARARGS | METH_KEYWORDS, "Foo Boo." ,
             NULL, NULL, 0, NULL 
        ;

        static PyModuleDef MyModule = 
            PyModuleDef_HEAD_INIT,
            "my_module",
            "Foo Boo.",
            -1,
            pyModuleMethods,
            NULL
        ;

        return PyModule_Create(&MyModule);
    

    void initializePython() 
        PyImport_AppendInittab("my_module", getModule);
        Py_Initialize();
    

;

int main() 
    static MyClass& myObj = MyClass::getInstance();
    myObj.initializePython();
    PyRun_SimpleString(
        "import my_module \n"
        "my_module.runTester() \n"
    );
    return 0;

问题是当我在PyRun_SimpleString 中运行my_module.runTester() 时。我收到以下错误消息:

SystemError:PyCFunction_Call 中的错误调用标志。 METH_OLDARGS 为否 支持时间更长!

我没有使用METH_OLDARGS。如您所见,我使用的是METH_VARARGS | METH_KEYWORDS。我在这里可能缺少什么?

我使用的是 Python 3.6 和 Windows 7 x64。

【问题讨论】:

【参考方案1】:

以下修改解决了这个问题:

static PyMethodDef pyModuleMethods[] = 
     "runTester", (PyCFunction)runTesterFunc, METH_VARARGS | METH_KEYWORDS, "Foo Boo." ,
     NULL, NULL, 0, NULL 
;

static struct PyModuleDef MyModule = 
    PyModuleDef_HEAD_INIT,
    "my_module",
    "Foo Boo.",
    -1,
    pyModuleMethods,
    NULL
;

【讨论】:

以上是关于无法从 Python C API 中内置的模块调用方法的主要内容,如果未能解决你的问题,请参考以下文章

Python中的模块

Python基础

python c api无法将任何模块导入新创建的模块

Python C API - 重新加载模块

从 C API 在 Python 模块中定义全局变量

Python / C-Api:向模块添加类