使用管道将大型 C 结构体直接传递给 Python(管道.传递.结构.Python...)

wufei123 发布于 2025-09-02 阅读(5)

使用管道将大型 c 结构体直接传递给 python

本教程旨在指导开发者如何通过管道将 C 语言结构体数据直接传递到 Python 脚本中进行处理。我们将详细介绍如何在 C 代码中使用 fwrite 将结构体数据写入标准输出,然后在 Python 中使用 subprocess 模块捕获输出,并利用 ctypes 模块将字节流解析为 Python 中的结构体对象。通过这种方法,可以实现高效的跨语言数据传输,避免中间文件,提高程序运行效率。

C 代码:将结构体数据写入标准输出

首先,我们需要在 C 代码中定义结构体,填充数据,然后使用 fwrite 函数将结构体数组的数据写入标准输出。 关键点在于包含 <stdio.h> 头文件,它包含了 fwrite 和 stdout 的声明。

#include <stdio.h>
#include <stdlib.h>

struct ChemicalDemands {
    double DO;
    double BOD;
    int time;
};

int main() {
    // 创建结构体数组
    struct ChemicalDemands ChemicalDemands[3];

    for (int i = 0; i < 3; i++) {
        ChemicalDemands[i].DO = 1.0;
        ChemicalDemands[i].BOD = 1.0;
        ChemicalDemands[i].time = i;
    }

    // 将数据写入标准输出
    fwrite(ChemicalDemands, sizeof(struct ChemicalDemands), 3, stdout);
    return 0;
}

注意事项:

  • 务必包含 <stdio.h> 头文件,否则 fwrite 和 stdout 将未定义,导致编译错误。
  • 使用编译器警告标志(如 -Wall, -Wextra, -Wpedantic)可以帮助你发现潜在的问题。不要忽略警告,尝试理解并解决它们。
Python 代码:读取管道数据并解析

接下来,我们需要编写 Python 代码来捕获 C 程序的标准输出,并将其解析为 Python 中的结构体对象。

import subprocess
import ctypes
import sys

# 定义与 C 结构体对应的 Python 结构体
class Results(ctypes.Structure):
    _fields_ = [("DO", ctypes.c_double),
                ("BOD", ctypes.c_double),
                ("time", ctypes.c_int)]

# 执行 C 程序并捕获输出
result = subprocess.run(["./a.out"], capture_output=True)

if result.returncode != 0:
    print("Error:", result.stderr.decode())
    sys.exit(1)

buffer = result.stdout

# 确定数组中的元素数量
num_elements = 3

# 从缓冲区创建 ctypes 数组
results_array = (Results * num_elements).from_buffer_copy(buffer)

# 打印第一个元素以验证数据是否正确
print(results_array[0].DO, results_array[0].BOD, results_array[0].time)

代码解释:

  1. ctypes 模块: ctypes 模块允许 Python 调用 C 动态链接库中的函数,并且可以定义与 C 结构体对应的 Python 类。
  2. Results 类: Results 类定义了与 C 结构体 ChemicalDemands 相同的字段,并且指定了每个字段的类型。 确保 Python 结构体的定义与 C 结构体的定义完全匹配,包括字段顺序和数据类型。
  3. subprocess.run 函数: subprocess.run 函数执行 C 程序,并捕获其标准输出和标准错误。
  4. capture_output=True: 这个参数确保标准输出和标准错误都被捕获。
  5. result.stdout: result.stdout 包含了 C 程序的标准输出,以字节流的形式存在。
  6. *`(Results num_elements):** 这创建了一个ctypes数组类型,其中Results是数组元素的类型,num_elements` 是数组的长度。
  7. .from_buffer_copy(buffer): 这个方法从缓冲区 buffer 中复制数据到 ctypes 数组中。

注意事项:

  • C 结构体和 Python 结构体的定义必须完全一致,包括字段类型和顺序。
  • 确保 C 程序编译后生成的可执行文件(例如 a.out)在 Python 脚本的同一目录下,或者在系统的 PATH 环境变量中。
  • num_elements 变量需要正确设置,以匹配 C 程序中写入的结构体数量。
  • 错误处理:检查 subprocess.run 的返回值,确保 C 程序成功执行。
总结

通过本教程,你学会了如何使用管道将 C 结构体数据直接传递到 Python 脚本中。这种方法可以避免中间文件,提高数据传输效率,特别适用于需要频繁进行跨语言数据交换的场景。记住,关键在于确保 C 结构体和 Python 结构体的定义一致,以及正确处理字节流数据。

以上就是使用管道将大型 C 结构体直接传递给 Python的详细内容,更多请关注知识资源分享宝库其它相关文章!

标签:  管道 传递 结构 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。