Компиляция python3 C расширений - PullRequest
1 голос
/ 27 февраля 2020

Я написал следующий код для моего 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!!!");
}

И когда я выполняю следующее в I Python3 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

Любая помощь приветствуется. Благодаря.

1 Ответ

2 голосов
/ 29 февраля 2020

Прежде всего, ваш 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;
}

И когда я выполняю следующее в оболочке I Python3, я получаю ошибку

Этот код обычно не вызывается из I Python. Он помещается в скрипт с именем setup.py, а затем выполняется из терминала, предоставляя задачи, которые должна вызывать функция setup, например,

$ python setup.py build_ext --inplace

, чтобы построить модуль расширения и поместить его в текущий каталог.

Конечно, вы также можете имитировать c в I Python:

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. Затем вы можете выполнить его в I Python через %run magi c:

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