微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Python C模块写入Bin文件并在C中读取文件

如何解决使用Python C模块写入Bin文件并在C中读取文件

我正在使用ctype将一些信息转换为C ++程序需要读取的二进制文件。该文件将包含带有字符串的行和其他带有double / double向量的行。

当我尝试在C ++中读取double的向量时,就会出现问题:向量的地址位于行的末尾,地址为11个字符,而在C ++中为8个字符。当我尝试直接将向量读入C ++出现时,由于这种差异而导致错误

可能的解决方案是逐个读取向量的元素,但这会降低性能

是否有可能在转换和读取过程中撕掉地址,或者忽略它以及整个向量?

这是我们要测试的一些代码

C ++ DLL模块:

#include<iostream>
#include<fstream>
#include<cstring>
#include <typeinfo>

using namespace std;


#define DLLEXPORT extern "C" __declspec(dllexport)


struct new_element {
    int id;
    unsigned int n_measures;
    double* value;
};

DLLEXPORT int writer_bin_file_c(const char* file_path,new_element structed_data)
{
    try {
        ofstream output_file(file_path);
        output_file.write((char*)&structed_data,sizeof(structed_data));  
        output_file << &structed_data;
        output_file.close();
    } catch (...) {
        return -1;
    }

    return 0;
}


DLLEXPORT new_element reader_bin_file_c(const char* file_path,new_element structed_data)
{
    try {
        ifstream input_file(file_path,ios::binary);
        input_file.read((char*)&structed_data,sizeof(structed_data));       
        input_file.close();
    } catch (...) {
        cout << "Error ao ler o arquivo" << endl;
    }

    return structed_data;
}

Python编写文件: 从ctypes import * 导入系统 将numpy导入为np

lib = CDLL(“ version4 / template_file.so”)

from ctypes import *
import sys
import numpy as np

lib = CDLL("version4/template_file.so")

class new_element(Structure):
    _fields_ = [
        ("id",c_int),("n_measures",c_uint),("value",POINTER(c_double))
    ]


template_file = lib
new_element_pointer = POINTER(new_element)

writer_bin_file = template_file.writer_bin_file_c
writer_bin_file.argtypes = [c_char_p,new_element]
writer_bin_file.restype = c_void_p 

reader_bin_file_c = template_file.reader_bin_file_c
reader_bin_file_c.restype = new_element

tam = 10
medida = np.arange(tam,dtype=c_double)
medida = medida.ctypes.data_as(POINTER(c_double))

element = new_element(4,tam)
element.value = medida

file_out = b'version4/element.txt'

answer = writer_bin_file(file_out,element)

C ++读取文件

#include<iostream>
#include<fstream>
#include<cstring>
#include <typeinfo>

using namespace std;

struct new_element {
    int id;
    unsigned int n_measures;
    double* value;
};


new_element reader_bin_file(const char* file_path,new_element structed_data)
{
    try {
        ifstream input_file(file_path);
        input_file.read((char*)&structed_data,sizeof(structed_data));    
        input_file.close();
    } catch (...) {
        cout << "Error ao ler o arquivo" << endl;
    }

    return structed_data;
}

int main(int argc,char const *argv[])
{
    new_element read_template;
    read_template = reader_bin_file(file_out,read_template);

    cout << "ID: " << read_template.id << endl;
    cout << "n_measures: " << read_template.n_measures << endl;
    cout << "Value: ";
    for (int i = 0;  i < read_template.n_measures; i++) 
    {
      cout << "( " << i << " ): " << read_template.value[i] << " | ";
    }
    cout << endl;


    return 0;
}


解决方法

您在这里有一个很深的误解。

一对字段

unsigned int n_measures;
double* value;

是一个数组(根据其名称推导),因此在编写器中,您必须保存n_measures的双精度值,而不是一个指针。因此,在阅读器中,您应该 read n_measures值,而不仅仅是指针。指针只是内存空间中的索引,而不是某些“全能的” C / C ++语言功能,它可以节省您所需的一切。

所以,在您的C ++编写代码中做

DLLEXPORT int writer_bin_file_c(const char* file_path,new_element structed_data)
{
  try {
    ofstream output_file(file_path);
    output_file.write((char*)&structed_data.id,sizeof(int));
    output_file.write((char*)&structed_data.n_measures,sizeof(int));
    // write out all the elements one by one,not just the pointer
    for (int i = 0 ; i < structed_data.n_measures ; i++)
       output_file.write((char *)&structed_data[i],sizeof(double));

    output_file.close();
} catch (...) {
    return -1;
}

return 0;

}

希望您至少在C ++方面有所了解。读取器代码类似-读取idn_measures,然后分配values数组并逐个读取值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。