我在尝试将双数组从C ++传递给Python时遇到了问题。我运行一个脚本来创建一个包含数据的二进制文件,然后将该数据读回一个数组,并尝试将该数组传递给Python。我在这里遵循了建议:how to return array from c function to python using ctypes以及我通过谷歌找到的其他页面。我可以编写一个工作正常的通用示例(就像上面链接的类似数组),但是当我尝试从二进制文件(下面的代码)传递数组时,程序崩溃时出现“ADDR未处理的异常”(ucrtbase。 dll)在python.exe中:一个无效参数被传递给一个认为无效参数致命的函数。“所以,我想知道是否有人有任何见解。
关于方法论的一个词:
现在,我只是想学习 - 这就是为什么我要经历复杂的保存到磁盘,加载和传递给Python的过程。最后,我将在科学模拟中使用它,其中从磁盘读取的数据需要由分布式计算/超级计算机生成。我想使用Python来简化绘图(matplotlib)和C ++的速度(迭代计算等)。
所以,我的代码。这会生成二进制文件:
for (int zzz = 0; zzz < arraysize; ++zzz)
{
for (int yyy = 0; yyy < arraysize; ++yyy)
{
for (int xxx = 0; xxx < arraysize; ++xxx)
{//totalBatP returns a 3 element std::vector<double> - dblArray3_t is basically that with a few overloaded operators (+,-,etc)
dblArray3_t BatP = B.totalBatP({ -5 + xxx * stepsize, -5 + yyy * stepsize, -5 + zzz * stepsize }, 37);
for (int bbb = 0; bbb < 3; ++bbb)
{
dataarray[loopind] = BatP[bbb];
++loopind;
...(end braces here)
FILE* binfile;
binfile = fopen("MBdata.bin", "wb");
fwrite(dataarray, 8, 3 * arraysize * arraysize * arraysize, binfile);
读取文件的代码:
DLLEXPORT double* readDblBin(const std::string filename, unsigned int numOfDblsToRead)
{
char* buffer = new char[numOfDblsToRead];
std::ifstream binFile;
binFile.open(filename, std::ios::in | std::ios::binary);
binFile.read(buffer, numOfDblsToRead);
double* dataArray = (double*)buffer;
binFile.close();
return dataArray;
}
接收数组的Python代码:
def readBDataWrapper(filename, numDblsToRead):
fileIO = ctypes.CDLL('./fileIO.dll')
fileIO.readDblBin.argtypes = (ctypes.c_char_p, ctypes.c_uint)
fileIO.readDblBin.restype = ctypes.POINTER(ctypes.c_double)
return fileIO.readDblBin(filename, numDblsToRead)
答案 0 :(得分:0)
这里可能存在一个问题
char* buffer = new char[numOfDblsToRead];
您可以在此处分配numOfDblsToRead
字节 。您可能需要numOfDblsToRead * sizeof(double)
。
与文件中的读数相同,您只能阅读numOfDblsToRead
字节。
答案 1 :(得分:0)
我弄明白了 - 至少看起来它起作用了。问题在于使用第一个代码块生成的二进制文件。我用ofstream交换了c风格的写作。我的假设也许是我正在使用代码以某种方式写入磁盘错误。无论如何,它现在似乎有效。
替换:
FILE* binfile;
binfile = fopen("MBdata.bin", "wb");
fwrite(dataarray, 8, 3 * arraysize * arraysize * arraysize, binfile);
使用:
std::ofstream binfile;
binfile.open("MBdata.bin", std::ios::binary | std::ios::out);
binfile.write(reinterpret_cast<const char*>(dataarray), std::streamsize(totaliter * sizeof(double)));
binfile.close();