Commit 4acf45ff authored by Stefan Behnel's avatar Stefan Behnel

Include a complete embedding example in the docs.

parent d62bc77b
# spam.pyx
# The following two lines are for test purposed only, please ignore them.
# distutils: sources = spam_main.c
# tag: py3only
TEXT_TO_SAY = 'Hello from Python!'
cdef public int say_hello_from_python() except -1:
print(TEXT_TO_SAY)
return 0
/* spam_main.c */
/* This include file is automatically generated by Cython for 'public' functions. */
#include "spam.h"
int
main(int argc, char *argv[])
{
PyObject *pmodule;
wchar_t *program;
program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
exit(1);
}
/* Add a built-in module, before Py_Initialize */
#if PY_MAJOR_VERSION == 2
/* Legacy Python 2.x version. */
if (PyImport_AppendInittab("spam", initspam) == -1)
#else
if (PyImport_AppendInittab("spam", PyInit_spam) == -1)
#endif
{
fprintf(stderr, "Error: could not extend in-built modules table\n");
exit(1);
}
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(program);
/* Initialize the Python interpreter. Required.
If this step fails, it will be a fatal error. */
Py_Initialize();
/* Optionally import the module; alternatively,
import can be deferred until the embedded script
imports it. */
pmodule = PyImport_ImportModule("spam");
if (!pmodule) {
PyErr_Print();
fprintf(stderr, "Error: could not import module 'spam'\n");
goto exit_with_error;
}
/* Now call into your module code. */
if (say_hello_from_python() < 0) {
PyErr_Print();
fprintf(stderr, "Error in Python code, exception was printed.\n");
goto exit_with_error;
}
/* ... */
/* Clean up after using CPython. */
PyMem_RawFree(program);
Py_Finalize();
return 0;
/* Clean up in the error cases above. */
exit_with_error:
PyMem_RawFree(program);
Py_Finalize();
return 1;
}
......@@ -6,7 +6,9 @@
Embedding Cython modules in C/C++ applications
**********************************************
This is a stub documentation page. PRs welcome.
**This is a stub documentation page. PRs very welcome.**
Quick links:
* `CPython docs <https://docs.python.org/3/extending/embedding.html>`_
......@@ -19,6 +21,11 @@ This is a stub documentation page. PRs welcome.
* `Embedding demo program <https://github.com/cython/cython/tree/master/Demos/embed>`_
* See the documentation of the `module init function
<https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function>`_
in CPython and `PEP 489 <https://www.python.org/dev/peps/pep-0489/>`_ regarding the module
initialisation mechanism in CPython 3.5 and later.
Initialising your main module
=============================
......@@ -37,3 +44,34 @@ The `PyImport_AppendInittab() <https://docs.python.org/3/c-api/import.html#c.PyI
function in CPython allows registering statically (or dynamically) linked extension
modules for later imports. An example is given in the documentation of the module
init function that is linked above.
Embedding example code
======================
The following is a simple example that shows the main steps for embedding a
Cython module (``spam.pyx``) in Python 3.x.
First, here is a Cython module that exports a C function to be called by external
code. Note that the ``say_hello_from_python()`` function is declared as ``public``
to export it as a linker symbol that can be used by other C files, which in this
case is ``spam_main.c``.
.. literalinclude:: ../../examples/tutorial/embedding/spam.pyx
The C ``main()`` function of your program could look like this:
.. literalinclude:: ../../examples/tutorial/embedding/spam_main.c
:linenos:
:language: c
(Adapted from the `CPython documentation
<https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function>`_.)
Instead of writing such a ``main()`` function yourself, you can also let
Cython generate one into your module's C file with the ``cython --embed``
option. Or use the
`cython_freeze <https://github.com/cython/cython/blob/master/bin/cython_freeze>`_
script to embed multiple modules. See the
`embedding demo program <https://github.com/cython/cython/tree/master/Demos/embed>`_
for a complete example setup.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment