Написание расширений (extensions) для Python на C

Введение

Примеры

  • 5

    Hello World с расширением C

    Следующий источник C файл (который мы будем называть hello.c для демонстрационных целей) производит модуль расширения имени hello , который содержит единственную функцию greet() :

     #include <Python.h>
    #include <stdio.h>
    
    #if PY_MAJOR_VERSION >= 3
    #define IS_PY3K
    #endif
    
    static PyObject *hello_greet(PyObject *self, PyObject *args)
    {
        const char *input;
        if (!PyArg_ParseTuple(args, "s", &input)) {
            return NULL;
        }
        printf("%s", input);
        Py_RETURN_NONE;
    }
    
    static PyMethodDef HelloMethods[] = {
        { "greet", hello_greet, METH_VARARGS, "Greet the user" },
        { NULL, NULL, 0, NULL }
    };
    
    #ifdef IS_PY3K
    static struct PyModuleDef hellomodule = {
        PyModuleDef_HEAD_INIT, "hello", NULL, -1, HelloMethods
    };
    
    PyMODINIT_FUNC PyInit_hello(void)
    {
        return PyModule_Create(&hellomodule);
    }
    #else
    PyMODINIT_FUNC inithello(void)
    {
        (void) Py_InitModule("hello", HelloMethods);
    }
    #endif
    
     

    Для компиляции файла с помощью gcc компилятора, выполните следующую команду в вашем любимом терминале:

    gcc /path/to/your/file/hello.c -o /path/to/your/file/hello

    Для выполнения greet() функцию , которую мы написали ранее, создать файл в том же каталоге, и назовите его hello.py

     import hello          # imports the compiled library
    hello.greet("Hello!") # runs the greet() function with "Hello!" as an argument
    
    
     
  • 0

    Передача открытого файла в C Extensions

    Передайте объект открытого файла из Python в код расширения C.

    Вы можете преобразовать файл дескриптора файла , используя число PyObject_AsFileDescriptor функции:

     PyObject *fobj;
    int fd = PyObject_AsFileDescriptor(fobj);
    if (fd < 0){
        return NULL;
    }
    
     

    Для того, чтобы преобразовать дескриптор файла целочисленного обратно в объект питона, используйте PyFile_FromFd .

     int fd; /* Existing file descriptor */
    PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1); 
  • 1

    Расширение C Использование C ++ и Boost

    Это базовый пример расширения C с использованием C ++ и подталкивания .

    Код C ++

    Код C ++, помещенный в hello.cpp:

    #include <boost/python/module.hpp>
    #include <boost/python/list.hpp>
    #include <boost/python/class.hpp>
    #include <boost/python/def.hpp>
    
    // Return a hello world string.
    std::string get_hello_function()
    {
       return "Hello world!";
    }
    
    // hello class that can return a list of count hello world strings.
    class hello_class
    {
    public:
    
       // Taking the greeting message in the constructor.
       hello_class(std::string message) : _message(message) {}
    
       // Returns the message count times in a python list.
       boost::python::list as_list(int count)
       {
          boost::python::list res;
          for (int i = 0; i < count; ++i) {
             res.append(_message);
          }
          return res;
       }
    
    private:
       std::string _message;
    };
    
    
    // Defining a python module naming it to "hello".
    BOOST_PYTHON_MODULE(hello)
    {
       // Here you declare what functions and classes that should be exposed on the module.
    
       // The get_hello_function exposed to python as a function.
       boost::python::def("get_hello", get_hello_function);
    
       // The hello_class exposed to python as a class.
       boost::python::class_<hello_class>("Hello", boost::python::init<std::string>())
          .def("as_list", &hello_class::as_list)
          ;   
    }
    
     

    Чтобы скомпилировать это в модуль python, вам понадобятся заголовки python и библиотеки boost. Этот пример был сделан на Ubuntu 12.04 с использованием python 3.4 и gcc. Boost поддерживается на многих платформах. В случае Ubuntu необходимые пакеты были установлены с использованием:

     sudo apt-get install gcc libboost-dev libpython3.4-dev
    
     

    Компиляция исходного файла в .so-файл, который впоследствии может быть импортирован как модуль, при условии, что он находится по пути python:

     gcc -shared -o hello.so -fPIC -I/usr/include/python3.4 hello.cpp -lboost_python-py34 -lboost_system -l:libpython3.4m.so
    
     

    Код Python в файле example.py:

     import hello
    
    print(hello.get_hello())
    
    h = hello.Hello("World hello!")
    print(h.as_list(3))
    
     

    Тогда python3 example.py даст следующий результат:

     Hello world!
    ['World hello!', 'World hello!', 'World hello!']
    
     

Синтаксис

Параметры

Примечания