Python ctypes 正在写入要由 C 可执行文件读取的数据

Python ctypes writing data to be read by C executable

我正在尝试学习如何使用 Python ctypes 库将数据写入 C 可执行文件可以轻松读取的文件。在我整理的小测试用例中,我 运行 遇到了 reading/writing 字符数组的一些问题。

目前,我有三个源文件。 write_struct.py 用两个创建一个简单的结构 条目,一个名为 git 的整数值和一个名为 command 的字符数组,然后使用 ctypes.fwrite 将结构写入文件。 read_struct.cread_struct.h 编译成一个可执行文件,该可执行文件在内部定义了与 write_struct.py 中的结构相同的结构,然后读入由 python 脚本写入的数据并将其打印出来。

目前,python 文件中分配了以下值(并非字面上所示的方式,向下滚动以查看实际代码):

git = 1
command = 'cp file1 file2'

并且当 运行 时,C 可执行文件打印以下内容:

git: 1
command:

我意识到问题几乎可以肯定是 command 变量在 python 脚本中的分配方式。我读过 c_char_p()(我目前用来初始化该变量中的数据的函数)不会创建指向可变内存的指针,应该使用 create_string_buffer(),但我不是确定这是如何将数据添加到结构或将其写入文件的。我想我也对将 pointers/their 数据写入文件一开始的工作方式感到困惑。执行此操作的最佳方法是什么?

提前感谢任何能够提供帮助的人!!

我的三个文件的代码如下,供参考:

write_struct.py:

"""
write_struct.py
"""

from ctypes import *

libc = cdll.LoadLibrary("libc.so.6")

class DataStruct(Structure):
    _fields_ = [("git", c_int),
                ("command", c_char_p)
                ]

def main():
    pydata = DataStruct(1, c_char_p("cp file1 file2"))

    libc.fopen.argtypes = c_char_p, c_char_p
    libc.fopen.restype = c_void_p

    libc.fwrite = libc.fwrite
    libc.fwrite.argtypes = c_void_p, c_size_t, c_size_t, c_void_p
    libc.fwrite.restype = c_size_t

    libc.fclose = libc.fclose
    libc.fclose.argtypes = c_void_p,
    libc.fclose.restype = c_int


    f = libc.fopen("stored_data", "wb")
    libc.fwrite(byref(pydata), sizeof(pydata), 1, f)
    libc.fclose(f)
    return 0

main()

read_struct.c:

/*
 * read_struct.c
 *
 */

#include "read_struct.h"

int main()
{
  data_struct cdata = malloc(DATASIZE);
  FILE *fp;
  if ((fp = fopen("stored_data", "r")) != NULL) {
    fread(cdata, DATASIZE, 1, fp);
    printf("git: %i\n", cdata->git);
    printf("command:");
    printf("%s\n", cdata->command);
    fclose(fp);
  } else {
    printf("Could not open file\n");
    exit(1);
  }
  return 0;
}

read_struct.h:

/*
 * read_struct.h
 *
 */

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

typedef struct _data_struct *data_struct;
struct _data_struct {
  int git;
  char command[40];
};
#define DATASIZE sizeof(struct _data_struct)

可以直接用Python写入二进制数据。 ctypes 可用于创建结构并支持位字段和联合,或者对于简单结构,可以使用 struct 模块。

from ctypes import *

class DataStruct(Structure):
    _fields_ = [("git", c_int),
                ("command", c_char * 40)] # You want array here, not pointer

pydata = DataStruct(1,b'cp file1 file2')  # byte string for initialization.
with open('stored_data','wb') as f:       # write file in binary mode
    f.write(pydata)                       # ctypes support conversion to bytes
import struct

# See struct docs for formatting codes
# i = int (native-endian.  Use <i to force little-endian, >i for big-endian)
# 40s = char[40] (zero-padded if initializer is shorter)
pydata = struct.pack('i40s',1,b'cp file1 file2')
with open('stored_data2','wb') as f:
    f.write(pydata)

参考:https://docs.python.org/3/library/struct.html#format-strings