在Python中调用C++扩展

Calling C++ extensions in Python

本文关键字:C++ 扩展 调用 Python      更新时间:2023-10-16

我正在尝试在MSVC++2010中使用C++扩展Python 3。我对这类东西完全陌生,而且我对C++也不是很精通。根据python文档和我之前在这里收到的帮助,我编写了以下代码,这些代码成功编译并运行:

#include <Python.h>
#include <iostream>
using namespace std;
static PyObject *SpamError;
static PyObject *spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;
    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return PyLong_FromLong(sts);
}
static PyMethodDef SpamMethods[] = {
    {"system",  spam_system, METH_VARARGS,
     "Execute a shell command."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};
static struct PyModuleDef spammodule = {
   PyModuleDef_HEAD_INIT,
   "spam",   /* name of module */
   NULL,     /* module documentation, may be NULL */
   -1,       /* size of per-interpreter state of the module,
                or -1 if the module keeps state in global variables. */
   SpamMethods
};

PyMODINIT_FUNC
PyInit_spam(void)
{
    PyObject *m;
    m = PyModule_Create(&spammodule);
    if (m == NULL)
        return NULL;
    SpamError = PyErr_NewException("spam.error", NULL, NULL);
    Py_INCREF(SpamError);
    PyModule_AddObject(m, "error", SpamError);
    return m;
}
int main(int argc, wchar_t *argv[])
{
    // Add a builtin module, before Py_Initialize
    PyImport_AppendInittab("spam", PyInit_spam);
    // Pass argv[0] to the Python Interpreter
    Py_SetProgramName(argv[0]);
    // Initialise the Python interpreter
    Py_Initialize();
    // Import module
    PyImport_ImportModule("spam");
    cout << "test" << endl;
    system("PAUSE");
}

不过,我仍然对一些事情不确定;我需要为此创建一个头文件吗?我应该怎么做?

此外,我最终应该如何通过python shell或在程序中调用扩展?

我已经用Boost Python完成了这项工作。它构建一个DLL或共享对象(取决于平台是Windows还是Linux)作为Python模块,然后您可以在Python中导入该模块并像使用任何其他模块一样使用。它直截了当,工作可靠。您已经有了您的cpp文件和头,所以您只需要编写包装器来公开您想要从Python中使用的函数/方法/类。我把包装纸放在我的cpp文件的底部。它们看起来像这样:

#include <boost/python.hpp>
BOOST_PYTHON_MODULE(my_module)
{
    boost::python::def("function_name", function, boost::python::args("start", "length", "offset", "boundry", "byte", "data", "variable" ), "docstring");
}

就是这样。