【问题标题】:Compiling python3 C extensions编译 python3 C 扩展
【发布时间】:2020-02-27 20:23:04
【问题描述】:

我为我的 CPython 扩展编写了以下代码:

#include <Python.h>
static PyObject *greeting(PyObject* self)
{
        return Py_BuildValue("s" , "Hello python modules!!!");
}

static char *my_docstring = "This is a sample docstring";

static PyMethodDef greeting_funcs[] = {
    {"greeting" , (PyCFunction)greeting , METH_NOARGS , my_docstring} , {NULL}
};

void initModule(void){
    Py_InitModule3("greeting" , greeting_funcs , "Module example!!!");
}

当我在 IPython3 shell 中执行以下操作时

from setuptools import setup , Extension
modules = [Extension('mod', sources=["/home/spm/python_module/mod.c"])] 
setup(ext_modules=modules) 

我得到了错误:

SystemExit: usage: ipython3 [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts]
or: ipython3 --help [cmd1 cmd2 ...]
or: ipython3 --help-commands
or: ipython3 cmd --help

error: no commands supplied

任何帮助表示赞赏。
谢谢。

【问题讨论】:

    标签: c python-3.x setuptools python-extensions


    【解决方案1】:

    首先,您的mod.c 不会编译。 Py_InitModule3 在 Python 3 中被移除;您必须创建一个 PyModuleDef 结构并添加一个名为 PyInit_{library name} 的初始化函数,该函数传递 PyModuleDef 引用 到PyModule_Create初始化模块:

    #include <Python.h>
    #define MY_DOCSTRING "This is a sample docstring"
    
    static PyObject *greeting(PyObject* self)
    {
        return Py_BuildValue("s" , "Hello python modules!!!");
    }
    
    static PyMethodDef greeting_funcs[] = {
        {"greeting" , (PyCFunction)greeting , METH_NOARGS , MY_DOCSTRING} , {NULL}
    };
    
    
    // python module definition
    static struct PyModuleDef greetingModule = {
        PyModuleDef_HEAD_INIT, "greeting", "Module example!!!", -1, greeting_funcs
    };
    
    // register module namespace
    PyMODINIT_FUNC PyInit_mod(void)
    {
        PyObject *module;
    
        module = PyModule_Create(&greetingModule);
        if (module == NULL)
            return NULL;
    
        return module;
    }
    

    当我在 IPython3 shell 中执行以下命令时,我得到了错误

    通常不会从 IPython 调用此代码。它被放入一个名为setup.py 的脚本中,然后从终端执行,提供setup 函数应该调用的任务,例如

    $ python setup.py build_ext --inplace
    

    构建扩展模块并将其放入当前目录。

    当然,你也可以在 IPython 中模仿:

    In [1]: import sys                                                                                                                                                                                                 
    
    In [2]: sys.argv.extend(["build_ext", "--inplace"])                                                                                                                                                                
    
    In [3]: from setuptools import setup, Extension                                                                                                                                                                    
    
    In [4]: modules = [Extension('mod', sources=["mod.c"])]                                                                                                                                                            
    
    In [5]: setup(ext_modules=modules)                                                                                                                                                                                 
    running build_ext
    ...
    
    In [6]: sys.argv = sys.argv[:1]
    

    但是,更好的解决方案是将设置代码写入setup.py 脚本。然后,您可以通过 %run 魔法在 IPython 中执行它:

    In [1]: %run setup.py build_ext --inplace                                                                                                                                                                          
    running build_ext
    building 'mod' extension
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 2019-12-10
      相关资源
      最近更新 更多