1
我目前正在做一個C庫的綁定,並且我有一些麻煩做一個函數與一個void指針數組綁定一個參數。如何用一個void指針數組作爲參數做一個OCaml綁定到一個C函數
我寫了一個簡單的示例綁定來向你展示我是如何做到的。
下面是OCaml的代碼:
type void
external function_c : string -> void array -> int -> void ref -> unit = "function_c"
let _ =
let int_arguments = [| ((Obj.magic 4) : void); ((Obj.magic 10) : void) |] in
let int_sum = ref 0 in
function_c "int" int_arguments (Array.length int_arguments) ((Obj.magic int_sum) : void ref);
print_int !int_sum;
print_endline ""
這裏是C代碼:
#include <stdio.h>
#include <string.h>
#include <caml/alloc.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>
void* function(char* type, void** numbers, int size) {
int i;
if(strcmp(type, "float") == 0) {
/* ... */
}
else if(strcmp(type, "int") == 0) {
int* result = malloc(sizeof(int));
int sum = 0;
for(i = 0 ; i < size ; i++) {
int* number = (int*) numbers[i];
sum += *number;
}
*result = sum;
return (void*) result;
}
return NULL;
}
CAMLprim value function_c(value type, value numbers, value size, value result) {
CAMLparam4(type, numbers, size, result);
int i;
char* c_type = String_val(type);
int c_size = Int_val(size);
if(strcmp(c_type, "float") == 0) {
/* ... */
}
else if(strcmp(c_type, "int") == 0) {
void** c_numbers = malloc(sizeof(void*) * size);
int* int_numbers = malloc(sizeof(int) * size);
int* int_result;
for(i = 0 ; i < c_size ; i++) {
int_numbers[i] = Int_val(Field(numbers, i));
c_numbers[i] = &int_numbers[i];
}
int_result = function(c_type, c_numbers, c_size);
Store_field(result, 0, Val_int(*int_result));
free(int_result);
free(c_numbers);
free(int_numbers);
}
CAMLreturn(Val_unit);
}
我看着很像一個黑客(因爲使用Obj.magic的),是由於malloc
和條件可能會慢得多。
有沒有更好的方式來編寫一個綁定到一個c函數與void指針數組作爲參數?
我想要綁定的函數的void **參數可以具有隻在運行時才知道的不同類型的參數。
謝謝。
它看起來像你的C函數需要一個int或浮點數組。將這個聲明爲OCaml方面的兩個不同的函數可能會好很多,一個是採用整數,另一個採用浮點數。你根本不需要使用'Obj.magic'。任何轉換都可以在C代碼中處理。即使在C這是一個糟糕的界面,它的價值。 – 2014-11-03 04:13:27
這只是一個例子。我想綁定的函數([libit]中的[jit_function_apply]](http://www.gnu.org/software/libjit/doc/libjit_5.html#index-jit_005ffunction_005fapply))可以具有不同類型的參數(例如,超過20種類型),並且多個類型可以在該函數的一次調用中位於數組中。 – antoyo 2014-11-03 13:24:49
我不太瞭解編寫C綁定,但是你有沒有考慮過使用[ctypes](https://github.com/ocamllabs/ocaml-ctypes)?它可以基於用OCaml寫的描述爲你生成C樁。 – 2014-11-04 13:42:58