简体   繁体   English

如何将 OCaml cstruct(或 Bigarray)传递给 C?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM