Zoeken…


Hallo wereld met C-extensie

Het volgende C-bronbestand (dat we hello.c zullen noemen voor demonstratiedoeleinden) produceert een uitbreidingsmodule met de naam hello die een enkele functie 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

Om het bestand te compileren met de gcc compiler, voert u de volgende opdracht uit in uw favoriete terminal:

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

Als u de functie greet() wilt uitvoeren die we eerder hebben geschreven, maakt u een bestand in dezelfde map en noemt u het hello.py

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

Een open bestand doorgeven aan C-extensies

Geef een open bestandsobject door van Python naar C-extensiecode.

U kunt het bestand converteren naar een integer bestandsdescriptor met behulp van de PyObject_AsFileDescriptor functie:

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

Gebruik PyFile_FromFd om een integer-bestandsdescriptor terug te converteren naar een python-object.

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

C Uitbreiding met c ++ en Boost

Dit is een basisvoorbeeld van een C-extensie met C ++ en Boost .

C ++ code

C ++ code in 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)
      ;   
}

Om dit in een python-module te compileren, hebt u de python-headers en de boost-bibliotheken nodig. Dit voorbeeld is gemaakt op Ubuntu 12.04 met behulp van python 3.4 en gcc. Boost wordt op veel platforms ondersteund. In het geval van Ubuntu werden de benodigde pakketten geïnstalleerd met behulp van:

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

Het bronbestand compileren in een .so-bestand dat later als een module kan worden geïmporteerd, mits het zich op het python-pad bevindt:

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

De python-code in het bestand example.py:

import hello

print(hello.get_hello())

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

Dan geeft python3 example.py de volgende uitvoer:

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow