标签: C++

  • C语言调用Python模块中的Python函数

    #include "Python.h"
    int main()
    {
            Py_Initialize();
            PyObject *pmodule = PyImport_ImportModule("os");
            //获取当前用户的id
            PyObject *pfunc = PyObject_GetAttrString(pmodule, "geteuid");
            PyObject *arg = Py_BuildValue("()");
            PyObject *result = PyObject_Call(pfunc, arg, NULL);
            long retval = PyLong_AsLong(result);
            printf("result: %ld\n", retval);
            Py_XDECREF(result);
            Py_FinalizeEx();
            return 0;
    }
    
    gcc -c -I/usr/include/python3.10  -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl  -lm -lm  test.c
    gcc -o test test.o  -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl  -lm
    

    执行后返回如下:

    $ ./test
    result: 1001
    这种方法可以调用普通Python函数

    Views: 1

  • C语言调用Python模块中的C函数

    C语言写的Python模块中可以有python函数,也可以有C函数。
    以下代码导入Python模块并执行其中的C函数
    ctest.c文件内容

    #include "Python.h"
    #include "test.h"
     int main(int argc, char *argv[])
    {
        PyObject *pmodule;
        int *result;
        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);
        }
        /* 把模块注册为内置模块 */
    
        if (PyImport_AppendInittab("test", PyInit_test) == -1) {
    
            fprintf(stderr, "Error: could not extend in-built modules table\n");
    
            exit(1);
    
        }
        /* 把命令行参数传给Python解释器 */
        Py_SetProgramName(program);
    
        /* 初始化Python,这一步是必须的. */
        Py_Initialize();
    
        /* 调用Python中的函数. */
        result = hello(1, 2);
        // PyErr_Print();
        printf("result:%d,%d,%lu\n", result[0], result[2], sizeof(result));
    
          /* Clean up after using CPython. */
        PyMem_RawFree(program);
        Py_FinalizeEx();
    
        return 0;
    
        /* Clean up in the error cases above. */
    exit_with_error:
        PyMem_RawFree(program);
        Py_Finalize();
        return 1;
    }
    

    编译

    gcc -o ctest -I/usr/include/python3.10 -I./ -L./ -ltest -lpython3.10 -Wl,-rpath . ctest.c
    

    如果是调用python自带的内置函数则不需要执行PyImport_AppendInittab,直接调用即可。
    只有C语言写的模块才能注册为内置模块

    关于Python解释器初始化的问题:
    cython官方文档上说如果不调用Py_Initialize()进行初始化极有可能会发生程序崩溃,但并没有说明什么情况下会崩溃。经过我的测试如果所调用的C函数不涉及Python代码,也不会调用其它可能会执行Python代码的函数则不会崩溃,反之就会发生断错误。也就是说只能在C语言的内存空间内执行。对于一些Python内置的C语言写的函数是可以不初始化就调用的,如果是那种需要import的就不可以了。

    Views: 1