python/numpy生成的二进制文件供C读取

har*_*ony 3 c python io binary numpy

我在 python 中创建了一个名为 random_from_python_int.dat 的 5*7 整数矩阵二进制文件,然后我从 C 中读取了这个二进制文件。不知何故我无法得到正确的数字这是我生成这个矩阵的 python 代码:

import numpy as np
np.random.seed(10)
filename = "random_from_python_int.dat"
fileobj = open(filename, mode='wb')
b = np.random.randint(100, size=(5,7))
b.tofile(fileobj)
fileobj.close
Run Code Online (Sandbox Code Playgroud)

这将生成一个矩阵

[ [  9 15 64 28 89 93 29]
  [  8 73 0  40 36 16 11]
  [ 54 88 62 33 72 78 49]
  [ 51 54 77 69 13 25 13]
  [ 92 86 30 30 89 12 65] ]
Run Code Online (Sandbox Code Playgroud)

但是当我从下面的 C 代码中读取它时:

#include <stdio.h>
#include <math.h>
int main()
{
  /* later changed 'double' to 'int', but that still had issues */
  double randn[5][7];

  char buff[256];
  FILE *latfile;

  sprintf(buff,"%s","random_from_python_int.dat");
  latfile=fopen(buff,"r");
  fread(&(randn[0][0]),sizeof(int),35,latfile);
  fclose(latfile);
  printf("\n %d     %d     %d     %d     %d     %d     %d",randn[0][0],randn[0][1],randn[0][2],randn[0][3],randn[0][4],randn[0][5],randn[0][6]);
  printf("\n %d     %d     %d     %d     %d     %d     %d",randn[1][0],randn[1][1],randn[1][2],randn[1][3],randn[1][4],randn[1][5],randn[1][6]);
  printf("\n %d     %d     %d     %d     %d     %d     %d",randn[2][0],randn[2][1],randn[2][2],randn[2][3],randn[2][4],randn[2][5],randn[2][6]);
  printf("\n %d     %d     %d     %d     %d     %d     %d",randn[3][0],randn[3][1],randn[3][2],randn[3][3],randn[3][4],randn[3][5],randn[3][6]);
  printf("\n %d     %d     %d     %d     %d     %d     %d\n",randn[4][0],randn[4][1],randn[4][2],randn[4][3],randn[4][4],randn[4][5],randn[4][6]);
}
Run Code Online (Sandbox Code Playgroud)

它会给我(调整空间以避免在stackoverflow站点上滚动):

      28      15         64      93         29 -163754450   9
      40      73          0      16         11 -163754450   8
      33      88         62      17         91 -163754450  54
     256       0 1830354560       0    4196011 -163754450 119
 4197424 4197493 1826683808 4196128 2084711472 -163754450  12
Run Code Online (Sandbox Code Playgroud)

我不确定出了什么问题。我已经尝试过在 python 中编写一个浮点矩阵并在 C 中将其读取为 double,它工作正常。但是这个整数矩阵不起作用。

ndi*_*dim 5

正如@tdube 所写,您的问题的快速摘要是:您的numpy实现写入 64 位整数,而您的 C 代码读取 32 位整数。

至于更多细节,请继续阅读。

当您将整数作为二进制补码写入和读取时,您需要确保以下三个整数属性对于二进制数据的生产者和消费者是相同的:整数大小、整数字节序、整数符号

符号性签署为双方numpy的和C,所以我们在这里有一个匹配。

字节顺序是不是一个问题,因为这里既numpy的和C程序是在同一台机器上,因此你可能有相同的字节顺序(不管是什么ENDIANNESS它实际上可能)。

但是,大小是问题。

默认情况下,numpy.random.randint使用np.int它的dtypenp.int文档中的大小未知,但在您的系统上却是 64 位。

所述numpy的标量引用列表几个整数类型(显着不包括np.int),其中三种组合是用于与外部程序接口鲁棒性的numpy

 # | numpy    | C
---+----------+---------
 1 | np.int32 | int32_t
 2 | np.int64 | int64_t
 3 | np.intc  | int
Run Code Online (Sandbox Code Playgroud)

如果您只是碰巧将numpy基于软件的接口连接到用于构建的相同 C 环境numpy,则使用 ( np.intc, int) 类型对(来自 case 3)看起来很安全。

但是,由于以下原因,我非常喜欢其中一种显式大小的类型(cases12):

  • 整数在numpy和 C 中的大小是绝对显而易见的。

  • 因此,您可以使用numpy生成的输出连接到使用不同 C 环境编译的程序,该环境可能具有不同的大小int

  • 您甚至可以使用numpy生成的输出与以完全不同的语言编写或为完全不同的机器编译并在其上运行的程序交互。但是,您必须考虑不同机器场景的字节序。