Python与C语言的交互调用指南
你可以使用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)
作者:C or Cpp