Embedding Python modules into C applications.
admin
2023-07-31 01:51:04
0

In official Doc. of Python 3, there is a short introduction to embedding Python in another application like C/C++ (seeEmbedding Python in Another Application).

The common procedure is as follows,

  1. write prototype C/C++ code and Python module codes.
    Note that in the Python codes conventions of python 2 & 3 can not be mixed together, which may cause segfault when running.

call.c

#include 

int
main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    if (argc < 3) {
        fprintf(stderr,\"Usage: call pythonfile funcname [args]\\n\");
        return 1;
    }

    Py_Initialize();
    pName = PyUnicode_FromString(argv[1]);
    /* Error checking of pName left out */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
        /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyLong_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, \"Cannot convert argument\\n\");
                    return 1;
                }
                /* pValue reference stolen here: */
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf(\"Result of call: %ld\\n\", PyLong_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,\"Call failed\\n\");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, \"Cannot find function \\\"%s\\\"\\n\", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, \"Failed to load \\\"%s\\\"\\n\", argv[1]);
        return 1;
    }
    Py_Finalize();
    return 0;
}

multiply.py

def multiply(a,b):
    print(\"Will compute\", a, \"times\", b)
    c = 0
    for i in range(0, a):
        c = c + b
    return c
  1. For a single C code, just build like
g++ call.c -o call `python3-config --cflags` `python3-config --ldflags`

This can be written as a shell like build.sh.
3. To run the code, write a shell named run.sh,

PYTHONPATH=. ./call multiply multiply 3 2

Here call is the main code, the two multiplys are the module and function names, respectively.
When running, this code gives,

Will compute 3 times 2
Result of call: 6

Note if no PYTHONPATH=. statement in front of the run command, there will be errors like ImportError: No module named multiply.

Someone suggested to add into the .py file

import sys
sys.path.insert(0, \"./path/to/your/modules/\")

I tested but not helpful.
BTW, the system path can be checked by

import sys
print(sys.path)

Useful commands in Python 3 are:

PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL;
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
PyObject* str_exc_type = PyObject_Repr(exc_type); //Now a unicode
object
PyObject* pyStr = PyUnicode_AsEncodedString(str_exc_type, \"utf-8\",
\"Error ~\");
const char *strExcType = PyBytes_AS_STRING(pyStr);
Py_XDECREF(str_exc_type);
Py_XDECREF(pyStr);

Py_XDECREF(exc_type);
Py_XDECREF(exc_value);
Py_XDECREF(exc_tb); 

Other useful tutorials are
Python嵌入C/C++ (Python核心编程)
C++中嵌入Python调用
Embedding Python in C/C++: Part I
Embedding Python in C/C++: Part II

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...