将C ++ double数组传递给Python导致崩溃

时间:2017-07-04 16:54:59

标签: python c++ arrays

我在尝试将双数组从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)

2 个答案:

答案 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();