本地整数大数组似乎是无符号的

6

我希望能够从C库中返回int数组给OCaml程序。为了做到这一点,我想将它们包装在Bigarray.Array1.t中。下面是C存根的一个小演示:

/* nativeintarray.c */ 
#include <stdio.h>
#include <assert.h>

#include <caml/memory.h>
#include <caml/bigarray.h>

CAMLprim value make_array(value unit) {
  CAMLparam1(unit);
  int* a = calloc (1, sizeof(int));
  a[0] = -1;
  /* Create a C-style bigarray, yes it is a memory leak */
  CAMLreturn(caml_ba_alloc_dims(CAML_BA_NATIVE_INT | CAML_BA_C_LAYOUT, 1, a, 1));
}

我的示例程序如下:

(* nativeintarray.ml *)
open Bigarray

(** Type for int arrays from/to C *)
type ivector = (nativeint, nativeint_elt, c_layout) Array1.t

external make_array : unit -> ivector = "make_array"

let () =
  Printf.printf "%nd\n" (make_array ()).{0}

由于nativeint是有符号整数,我希望程序输出-1,但结果却是:

% ocamlbuild nativeintarray_c.o                                        
Finished, 1 target (0 cached) in 00:00:00.
% ocamlbuild -package bigarray -lflags nativeintarray_c.o nativeintarray.native
Finished, 4 targets (0 cached) in 00:00:00.
% ./nativeintarray.native 
4294967295

正如我所说的,我天真地期望 nativeint 与我本地 C 编译器中的 int 匹配,但显然并非如此。有人能解释一下吗?

平台: Ocaml 4.02.3,gcc 6.1.1,全部为 64 位。

2个回答

3
请问您是否在您的环境中检查过 sizeof(int) 是否真的是8?如果你使用的是Win64操作系统,OCaml 4.03.0和x86_64-w64-mingw32-gcc(Cygwin的MinGW64编译器)组合,你的代码会像你描述的一样运行(打印出4294967295而不是-1),此时sizeof(int)并不返回8,而是4。将int改为long long即可解决该问题。我不是C语言大师,但OCaml的nativeint可能并不是底层C编译器的int类型。

2

在C语言中,64位平台下sizeof(int)可能不是8

如果您想在C绑定中使用nativeint类型,最简单的方法是包含<caml/config.h>文件并使用其中定义的intnat类型。

因此,重新编写您的示例:

/* nativeintarray.c */
#include <stdio.h>
#include <assert.h>

#include <caml/config.h>
#include <caml/memory.h>
#include <caml/bigarray.h>

CAMLprim value make_array(value unit) {
  CAMLparam1(unit);
  intnat* a = calloc (1, sizeof(intnat));
  a[0] = -1;
  /* Create a C-style bigarray, yes it is a memory leak */
  CAMLreturn(caml_ba_alloc_dims(CAML_BA_NATIVE_INT | CAML_BA_C_LAYOUT, 1, a, 1));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接