[C.C++] Python调用C语言

353 0
Honkers 2025-6-3 12:58:00 | 显示全部楼层 |阅读模式

你可以使用Python的ctypes模块来调用C语言编写的函数。这个模块允许Python与动态链接库进行交互,从而调用C函数。

简单示例

首先,创建一个C语言源文件,比如example.c:

  1. #include <stdio.h>
  2. // 定义一个简单的C函数
  3. int add(int a, int b) {
  4. return a + b;
  5. }
复制代码

然后,编译这个C文件为动态链接库(在Unix系统中,通常是.so文件;在Windows中,通常是.dll文件):

在Unix系统中,可以使用以下命令:

  1. gcc -shared -o example.so -fPIC example.c
复制代码

在Windows系统中,可以使用以下命令:

  1. gcc -shared -o example.dll -fPIC example.c
复制代码

接下来,创建一个Python脚本,比如example.py,在其中调用这个C函数:

  1. import ctypes
  2. # 加载动态链接库
  3. lib = ctypes.CDLL('./example.so') # Unix系统
  4. # lib = ctypes.CDLL('./example.dll') # Windows系统
  5. # 调用C函数
  6. result = lib.add(4, 5)
  7. print("Result:", result)
复制代码

在这个示例中,ctypes.CDLL()用于加载编译后的动态链接库,然后你可以像调用Python函数一样调用C函数。

从C语言返回数组到python

方法一:

在C语言里动态分配内存创建数组,返回数组指针到python,最后在python释放内存
比如example.c:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义一个简单的C函数,返回一个整数数组
  4. int* return_array(int size) {
  5. int* arr = (int*)malloc(size * sizeof(int));
  6. for (int i = 0; i < size; i++) {
  7. arr[i] = i * 2; // 填充数组
  8. }
  9. return arr;
  10. }
复制代码

然后,编译这个C文件为动态链接库。接下来,创建一个Python脚本,比如example.py,在其中调用这个C函数并返回数组:

  1. import ctypes
  2. # 加载动态链接库
  3. lib = ctypes.CDLL('./example.so') # Unix系统
  4. # lib = ctypes.CDLL('./example.dll') # Windows系统
  5. # 定义返回值类型为指针
  6. lib.return_array.restype = ctypes.POINTER(ctypes.c_int)
  7. # 调用C函数并返回数组
  8. size = 5
  9. arr_ptr = lib.return_array(size)
  10. arr = [arr_ptr[i] for i in range(size)]
  11. # 打印数组
  12. print("Array:", arr)
  13. # 释放内存
  14. lib.free(arr_ptr)
复制代码

方法二:

在python中创建数组,把数组指针传给C语言,这样在C语言操作数组后不需要返回,直接修改了python的数组。

C代码(假设文件名为 example.c):

  1. #include <stdio.h>
  2. // 定义一个简单的C函数,接受一个整数数组的指针和数组的长度作为参数
  3. void modify_array(int *arr, int size) {
  4. // 在这个示例中,我们将数组中的每个元素乘以2
  5. for (int i = 0; i < size; ++i) {
  6. arr[i] *= 2;
  7. }
  8. }
复制代码

编译这个C代码并生成共享库,接下来,我们将在Python中使用ctypes来加载共享库,并调用modify_array函数,将数组指针传递给C。

Python代码:

  1. import ctypes
  2. # 加载共享库
  3. lib = ctypes.CDLL('./example.so')
  4. # 定义modify_array函数的参数类型
  5. lib.modify_array.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int]
  6. def modify_array_from_python(arr):
  7. # 将Python列表转换为C数组
  8. c_arr = (ctypes.c_int * len(arr))(*arr)
  9. # 调用C函数,并将C数组的指针传递给它
  10. lib.modify_array(c_arr, len(arr))
  11. # 将修改后的数组重新转换为Python列表
  12. modified_arr = list(c_arr)
  13. return modified_arr
  14. # 在Python中创建一个数组并传递给C函数进行修改
  15. array_from_python = [1, 2, 3, 4, 5]
  16. modified_array = modify_array_from_python(array_from_python)
  17. 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

  1. import ctypes
  2. from array import array
  3. # 加载共享库
  4. lib = ctypes.CDLL('./example.so')
  5. # 定义modify_array函数的参数类型
  6. lib.modify_array.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int]
  7. def modify_array_from_python(arr):
  8. # 将Python数组转换为C数组
  9. c_arr = (ctypes.c_int * len(arr))(*arr)
  10. # 调用C函数,并将C数组的指针传递给它
  11. lib.modify_array(c_arr, len(arr))
  12. # 将修改后的C数组的值拷贝回Python数组
  13. modified_arr = array('i', c_arr)
  14. return modified_arr
  15. # 在Python中创建一个数组并传递给C函数进行修改
  16. array_from_python = array('i', [1, 2, 3, 4, 5]) # 其类型为'i'(即int类型)
  17. modified_array = modify_array_from_python(array_from_python)
  18. print("Modified Array from C:", modified_array)
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4014
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行