[英]How to pass an OCaml cstruct (or Bigarray) to C?
I want to pass a buffer of a network packet to C.我想将网络数据包的缓冲区传递给 C。 I already figured out how to do that for simple OCaml types but I don't know how to pass a buffer from this CStruct library.我已经想出了如何为简单的 OCaml 类型做到这一点,但我不知道如何从这个 CStruct 库中传递一个缓冲区。
The library that I'm using uses https://github.com/mirage/ocaml-cstruct which I don't know why but looks like it mimics a C struct, so I guess it should be easy to pass this as a buffer to C.我正在使用的库使用https://github.com/mirage/ocaml-cstruct我不知道为什么但看起来它模仿了 C 结构,所以我想应该很容易将它作为缓冲区传递至 C。
This is how the buffer is created in my code:这是在我的代码中创建缓冲区的方式:
let buf = Cstruct.create size in
If we look at its code, it calls https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.ml#L98 which is如果我们查看它的代码,它会调用https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.ml#L98这是
let buffer = Bigarray_compat.(Array1.create char c_layout len) in
{ buffer ; len ; off = 0 }
For a recent version of OCaml, Bigarray is just the standar lib Bigarray, it's simply a module that does对于最新版本的 OCaml,Bigarray 只是标准库 Bigarray,它只是一个模块
include Stdlib.Bigarray
I couldn't find anything about passing a bigarray to C as a pointer that can be read.我找不到任何关于将 bigarray 传递给 C 作为可以读取的指针的信息。
interface.cc:接口.cc:
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include <caml/alloc.h>
#include <caml/bigarray.h>
uint8_t *return_big_array()
{
static const value *make_and_fill_array_closure = NULL;
if (make_and_fill_array_closure == NULL)
{
make_and_fill_array_closure = caml_named_value("make_and_fill_array");
if (make_and_fill_array_closure == NULL)
{
printf("couldn't find OCaml function");
std::exit(1);
}
}
value bigArrayValue = caml_callback(*make_and_fill_array_closure, Val_unit);
void *bigArrayPointer = Caml_ba_data_val(bigArrayValue);
uint8_t *p = (uint8_t *)bigArrayPointer;
return p;
}
main.cc主文件
#include <stdio.h>
#include <caml/callback.h>
extern uint8_t* return_big_array();
int main(int argc, char ** argv)
{
/* Initialize OCaml code */
caml_startup(argv);
/* Do some computation */
uint8_t* p = return_big_array();
//Should print 5
printf("first element: %d \n", p[0]);
return 0;
}
bigarray.ml:大数组.ml:
open Format
let make_byte_array len =
Bigarray.Array1.create Bigarray.int8_signed Bigarray.c_layout len
let make_and_fill_array () =
let b = make_byte_array 10 in
let s = Bigarray.Array1.fill b 5 in
b
let () = Callback.register "make_and_fill_array" make_and_fill_array
Compile:编译:
ocamlopt -output-obj -o s.o bigarray.ml
g++ -o bigarray -I $(ocamlopt -where) \
main.cc interface.cc s.o $(ocamlopt -where)/libasmrun.a -ldl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.