【发布时间】:2021-01-31 07:32:52
【问题描述】:
我正在使用ctypes 转换二进制文件中的一些信息,这些信息需要由 C++ 程序读取。该文件将包含带有字符串的行和其他带有双精度/双精度向量的行。
当我尝试在 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 写入文件:
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;
}
【问题讨论】:
-
首先以二进制模式打开文件;如果您使用的是 Windows,将会有所不同,这是其他操作系统上的良好做法。
-
谢谢,我忘记了!