Python调用C语言

文章介绍了如何使用Python的ctypes模块与C语言进行交互,包括如何编译C文件为动态链接库,以及如何在Python中调用C函数,包括返回数组和修改Python数组的方法。
摘要由CSDN通过智能技术生成

你可以使用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)

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值