Extending & Embedding Python Using C - Embedding
Written by Mike James   
Tuesday, 13 August 2024
Article Index
Extending & Embedding Python Using C - Embedding
Embedding Under Linux
Python or C?
Embedded Debugging

If you know how to extend Python you also know how to embed it. This even has advanatages from the point of view of testing. This is an extract from the new book by Mike James that helps you combine the speed and power of C with the versatility and ease-of-programming of Python.

Extending & Embedding Python Using C

By Mike James

extendPython360

Buy from Amazon.

Contents

       Preface

  1. Extending And Embedding Python
  2. A First C Module Using Linux 
  3. A First C Module Using Windows
  4. Module Basics
        Extract: A First Module
        Extract: 
    Pi 
  5. Arguments
  6. Returning Python Objects
  7. Objects And Attributes
  8. More Complex Objects – Tuples, Lists and Dicts
  9. Errors, Exceptions And Reference Counting
        Extract:
    Exceptions 
  10. Bytes And Strings
  11. Modules And Attributes
  12. New Types
  13. Advanced Types
  14. Threads And The GIL
  15. Embedding Python ***NEW!!!

<ASIN:B0CK3X93KF>

So far we have only been considering extending Python by creating new modules which can be loaded into a Python program. A second approach to the problem is to embed the Python system within a C program. This is very similar to the task of extending Python and with a few small changes everything we have looked at so far applies to embedding Python.

Simple Embedding

The simplest way of embedding Python in a C program is to get it to execute a Python program without interacting with the C program. This isn’t the usual way you want to do things, but it serves to get started. To load the Python interpreter you need to use:

Py_Initialize()

This loads and initializes the Python interpreter and all of the Python API functions. In principle, you should never use a Python C function before initialization, but there are exceptions.

When you are finished using Python you should unload it using:

Py_FinalizeEx()

There are many custom configurations that you can set to make the Python interpreter behave exactly as you want it. Most of these are obvious, if sometimes fiddly, and we will ignore them and concentrate on using the interpreter.

Once the interpreter is loaded, it just sits there waiting for you to give is some Python code to run. As well as the interpreter the entire Python runtime is loaded and this you can use via the C API without giving the interpreter some code to execute. This differs from the situation with an extension where the Python interpreter is loaded and starts running code which loads and uses your extension.

The simplest example of using the Python interpreter to run a Python program is:

#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main(int argc, char *argv[])
{
      Py_Initialize();
      PyRun_SimpleString("from time import time,ctime\n"
                  "print('Today is', ctime(time()))\n");
      Py_FinalizeEx();    
  return 0;
}

The program simply loads the Python interpreter and then runs a small program which displays the current time and date. Notice that to run this program you need to compile it to an executable, not a shared library, and how this is achieved differs on Linux and Windows.

Embedding Under Windows

Under Windows, using VS Code and the Microsoft C compiler, the tasks.json file would be:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: cl.exe build active file",
            "command": "cl.exe",
            "args": [
                "/Zi",
                "/EHsc",
                "/nologo",
                "/IC:/Users/user/AppData/Local/
                     Programs/Python/Python311/include", 
                "/Fe${fileDirname}\\
${fileBasenameNoExtension}.exe", "${file}", "/link /LIBPATH:C:/Users/user/AppData/
Local/Programs/Python/Python311/libs" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$msCompile" ], "group": { "kind": "build", "isDefault": true }, "detail": "Task generated by Debugger." } ], "version": "2.0.0" }

This is just the usual Task for building and running a .exe file. Debugging it also standard for an exe but, of course, you can’t debug the Python code using a C debugger.



Last Updated ( Tuesday, 13 August 2024 )