Я пытаюсь узнать, как использовать библиотеку Python ctypes для записи данных в файл, который может быть легко прочитан исполняемыми файлами C. В небольшом тестовом примере, который я собрал, у меня возникают некоторые проблемы с чтением / записью массивов символов.
На данный момент у меня есть три исходных файла. write_struct.py
создает простую структуру с двумя записями, целочисленным значением с именем git
и массивом символов с именем command
, затем записывает структуру в файл, используя ctypes.fwrite
. read_struct.c
и read_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()
, однако я не уверен, как это работает либо с добавлением этих данных в структуру, либо с записью их в файл. Я думаю, что я также запутался в том, как в первую очередь работает запись указателей / их данных в файл. Каков лучший способ go сделать это?
Заранее спасибо всем, кто сможет помочь !!
Код моих трех файлов приведен ниже для справки:
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)