扩展/嵌入 FAQ

Can I create my own functions in C?

Yes, you can create built-in modules containing functions, variables, exceptions and even new types in C. This is explained in the document 扩展和嵌入 Python 解释器 .

Most intermediate or advanced Python books will also cover this topic.

Can I create my own functions in C++?

Yes, using the C compatibility features found in C++. Place extern "C" { ... } around the Python include files and put extern "C" before each function that is going to be called by the Python interpreter. Global or static C++ objects with constructors are probably not a good idea.

Writing C is hard; are there any alternatives?

There are a number of alternatives to writing your own C extensions, depending on what you’re trying to do.

Cython and its relative Pyrex are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having to learn Python’s C API.

If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library’s data types and functions with a tool such as SWIG . SIP , CXX Boost ,或 Weave are also alternatives for wrapping C++ libraries.

How can I execute arbitrary Python statements from C?

The highest-level function to do this is PyRun_SimpleString() which takes a single string argument to be executed in the context of the module __main__ 并返回 0 对于成功和 -1 when an exception occurred (including SyntaxError ). If you want more control, use PyRun_String() ; see the source for PyRun_SimpleString() in Python/pythonrun.c .

How can I evaluate an arbitrary Python expression from C?

Call the function PyRun_String() from the previous question with the start symbol Py_eval_input ; it parses an expression, evaluates it and returns its value.

How do I extract C values from a Python object?

That depends on the object’s type. If it’s a tuple, PyTuple_Size() returns its length and PyTuple_GetItem() returns the item at a specified index. Lists have similar functions, PyList_Size() and PyList_GetItem() .

For bytes, PyBytes_Size() returns its length and PyBytes_AsStringAndSize() provides a pointer to its value and its length. Note that Python bytes objects may contain null bytes so C’s strlen() should not be used.

To test the type of an object, first make sure it isn’t NULL , and then use PyBytes_Check() , PyTuple_Check() , PyList_Check() ,等。

There is also a high-level API to Python objects which is provided by the so-called ‘abstract’ interface – read Include/abstract.h for further details. It allows interfacing with any kind of Python sequence using calls like PySequence_Length() , PySequence_GetItem() , etc. as well as many other useful protocols such as numbers ( PyNumber_Index() et al.) and mappings in the PyMapping APIs.

How do I use Py_BuildValue() to create a tuple of arbitrary length?

You can’t. Use PyTuple_Pack() 代替。

How do I call an object’s method from C?

The PyObject_CallMethod() function can be used to call an arbitrary method of an object. The parameters are the object, the name of the method to call, a format string like that used with Py_BuildValue() , and the argument values:

PyObject *
PyObject_CallMethod(PyObject *object, const char *method_name,
                    const char *arg_format, ...);