你可以使用Python的ctypes模块来调用C语言编写的函数。这个模块允许Python与动态链接库进行交互,从而调用C函数。
简单示例
首先,创建一个C语言源文件,比如example.c: - #include <stdio.h>
- // 定义一个简单的C函数
- int add(int a, int b) {
- return a + b;
- }
复制代码
然后,编译这个C文件为动态链接库(在Unix系统中,通常是.so文件;在Windows中,通常是.dll文件):
在Unix系统中,可以使用以下命令: - gcc -shared -o example.so -fPIC example.c
复制代码
在Windows系统中,可以使用以下命令: - gcc -shared -o example.dll -fPIC example.c
复制代码
接下来,创建一个Python脚本,比如example.py,在其中调用这个C函数: - import ctypes
- # 加载动态链接库
- lib = ctypes.CDLL('./example.so') # Unix系统
- # lib = ctypes.CDLL('./example.dll') # Windows系统
- # 调用C函数
- result = lib.add(4, 5)
- print("Result:", result)
复制代码
在这个示例中,ctypes.CDLL()用于加载编译后的动态链接库,然后你可以像调用Python函数一样调用C函数。
从C语言返回数组到python
方法一:
在C语言里动态分配内存创建数组,返回数组指针到python,最后在python释放内存 比如example.c: - #include <stdio.h>
- #include <stdlib.h>
- // 定义一个简单的C函数,返回一个整数数组
- int* return_array(int size) {
- int* arr = (int*)malloc(size * sizeof(int));
- for (int i = 0; i < size; i++) {
- arr[i] = i * 2; // 填充数组
- }
- return arr;
- }
复制代码
然后,编译这个C文件为动态链接库。接下来,创建一个Python脚本,比如example.py,在其中调用这个C函数并返回数组: - import ctypes
- # 加载动态链接库
- lib = ctypes.CDLL('./example.so') # Unix系统
- # lib = ctypes.CDLL('./example.dll') # Windows系统
- # 定义返回值类型为指针
- lib.return_array.restype = ctypes.POINTER(ctypes.c_int)
- # 调用C函数并返回数组
- size = 5
- arr_ptr = lib.return_array(size)
- arr = [arr_ptr[i] for i in range(size)]
- # 打印数组
- print("Array:", arr)
- # 释放内存
- lib.free(arr_ptr)
复制代码
方法二:
在python中创建数组,把数组指针传给C语言,这样在C语言操作数组后不需要返回,直接修改了python的数组。
C代码(假设文件名为 example.c): - #include <stdio.h>
- // 定义一个简单的C函数,接受一个整数数组的指针和数组的长度作为参数
- void modify_array(int *arr, int size) {
- // 在这个示例中,我们将数组中的每个元素乘以2
- for (int i = 0; i < size; ++i) {
- arr[i] *= 2;
- }
- }
复制代码
编译这个C代码并生成共享库,接下来,我们将在Python中使用ctypes来加载共享库,并调用modify_array函数,将数组指针传递给C。
Python代码: - import ctypes
- # 加载共享库
- lib = ctypes.CDLL('./example.so')
- # 定义modify_array函数的参数类型
- lib.modify_array.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int]
- def modify_array_from_python(arr):
- # 将Python列表转换为C数组
- c_arr = (ctypes.c_int * len(arr))(*arr)
-
- # 调用C函数,并将C数组的指针传递给它
- lib.modify_array(c_arr, len(arr))
-
- # 将修改后的数组重新转换为Python列表
- modified_arr = list(c_arr)
- return modified_arr
- # 在Python中创建一个数组并传递给C函数进行修改
- array_from_python = [1, 2, 3, 4, 5]
- modified_array = modify_array_from_python(array_from_python)
- print("Modified Array from C:", modified_array)
复制代码
- ctypes.c_int 是一个表示C语言中int类型的ctypes类型。
- ctypes.POINTER(ctypes.c_int) 则表示一个指向 ctypes.c_int 类型对象的指针。
- (ctypes.c_int * len(arr)) 创建了一个包含len(arr)个ctypes.c_int元素的C类型数组。
- (*arr) 将Python列表arr解引用,将其内容传递给ctypes.c_int数组的初始化器。
为了更清晰的表达数组类型,可以不用list列表,可以用Python的内置数组模块 array - import ctypes
- from array import array
- # 加载共享库
- lib = ctypes.CDLL('./example.so')
- # 定义modify_array函数的参数类型
- lib.modify_array.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int]
- def modify_array_from_python(arr):
- # 将Python数组转换为C数组
- c_arr = (ctypes.c_int * len(arr))(*arr)
-
- # 调用C函数,并将C数组的指针传递给它
- lib.modify_array(c_arr, len(arr))
-
- # 将修改后的C数组的值拷贝回Python数组
- modified_arr = array('i', c_arr)
- return modified_arr
- # 在Python中创建一个数组并传递给C函数进行修改
- array_from_python = array('i', [1, 2, 3, 4, 5]) # 其类型为'i'(即int类型)
- modified_array = modify_array_from_python(array_from_python)
- print("Modified Array from C:", modified_array)
复制代码 |