C语言中调用Python函数get_map_live

1. 搭建Python、Cython、NumPy环境

1.1 Linux基于miniconda搭建python环境

1.1.1 miniconda3下载安装

  sh Miniconda3-latest-Linux-x86_64.sh -h       # 查看安装帮助信息  
  sh Miniconda3-latest-Linux-x86_64.sh -p /path # 开始安装到指定目录/path
  • 安装完成后,打开terminal,取消base环境自动激活:
  conda config --set auto_activate_base false  # 如果提示找不到conda,请检查系统环境变量设置`vim ~/.bashrc`

1.1.2 conda创建python虚拟环境,安装cython、numpy

  • 打开terminal,创建 python3.9.18环境,假设虚拟环境命名为py3:

    conda create -n py3 python=3.9.18   # 等待创建完成
  • 进入py3虚拟环境,安装numpy、cython等:

    conda activate py3   # 激活py3环境  
    conda install cython=3.0.8 numpy=1.24.1

1.2 windows cygwin搭建python环境

  • python
  • numpy
  • cython(0.29.33) # 通过pip安装:python3 -m pip install cython

2. py转c

2.1 编辑py文件

cython_test.py为例,打开文件,编辑内容:

  • 顶部添加 # cython:language_level=3
  • 编辑 def get_map_live(camera)cdef public get_map_live(camera)
  • 修改 cython_test.py文件后缀为 .pyx

2.2 .pyx转.c .h

cython cython_test.pyx  # 会在当前目录生成 cython_test.c cython_test.h文件

3. c语言调用 get_map_live函数,从设备端获取 map

3.1 相关头文件

#include <Python.h>
#include <cython_test.h>
#include <numpy/arrayobject.h>

3.2 接口调用

  • 模块初始化,注意其中三处 cython_test,对应的是cython_test.pyx的文件名
int status=PyImport_AppendInittab("cython_test", PyInit_cython_test);
if(status==-1){
    printf("PyImport_AppendInittab error.\n");
    return -1;
}
printf("init\n");
Py_Initialize();

PyObject *module = PyImport_ImportModule("cython_test");
if(module==NULL){
    printf("PyImport_ImportModule error.\n");
    PyErr_Print();  // 打印详细报错信息
    Py_Finalize();
    return 1;
}
  • 准备 get_map_live函数的参数,此处为 camara字典
PyObject * camera = PyDict_New();
PyDict_SetItemString(camera, "ipAddress", Py_BuildValue("s", "192.168.1.10"));
PyDict_SetItemString(camera, "username", Py_BuildValue("s", "admin"));
PyDict_SetItemString(camera, "password", Py_BuildValue("s", "admin"));
  • 调用函数,获取map,python输出数据类型为 int16,所以此处数据类型转为 unsigned short
unsigned short *pframebuf = (unsigned short *)PyArray_DATA(get_map_live(camera));

4. 编译

准备工作:获取相关库路径,gcc编译时需要做链接,以cygwin为例

python3-config --includes  # 输出  -I/usr/include/python3.9
python3-config --ldflags   # 输出  -L/usr/lib -lpython3.9 -lcrypt -lintl -ldl  
python3 -c "import numpy; print(numpy.get_include())"   # 输出 /usr/lib/python3.9/site-packages/numpy/core/include

4.1 gcc编译

编译环境:ubuntu18.04 gcc7.5.0,编译时链接python,numpy

gcc -Wall -o main cython_test.c main.c -I. -I/usr/include/python3.9 -L/usr/lib -lpython3.9 -lcrypt -lintl -ldl -I/usr/lib/python3.9/site-packages/numpy/core/include
最后修改:2024 年 04 月 28 日
如果觉得我的文章对你有用,请随意赞赏