Python Language
Extensies schrijven
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!']