Call a function in a shared library/OCaml: Difference between revisions

m
prevent rem successive spaces
mNo edit summary
m (prevent rem successive spaces)
 
(4 intermediate revisions by the same user not shown)
Line 13:
| String of string
| Ptr of pointer
| Void
 
type return_type =
Line 20 ⟶ 21:
| Return_string
| Return_ptr
| Return_void
 
type rtld_flags =
Line 126 ⟶ 128:
ffi_status status;
ffi_type *rtype;
int ffi_prep_cif_failed = 0;
 
nargs = Wosize_val(ml_args);
Line 188 ⟶ 191:
arg_values[i] = &Field(v,0);
} break;
case 5: /* Void */
caml_invalid_argument("fficall");
break;
}
}
Line 206 ⟶ 212:
case 4: /* Return_ptr */
rtype = &ffi_type_pointer;
break;
case 5: /* Return_void */
rtype = &ffi_type_uint;
break;
}
 
status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rtype, arg_types);
if (status != FFI_OK) {
ffi_prep_cif_failed = 1;
{
goto freeandfail;
for (i = 0; i < nargs; i++) free(arg_values[i]);
free(arg_values);
free(arg_types);
failwith("ffi_prep_cif");
}
 
Line 243 ⟶ 249:
ffi_call(&cif, (void (*)(void)) func_handle, &result, arg_values);
ml_ret = Val_tagged( (value) result, 4);
} break;
case 5: /* Return_void */
{ ffi_arg result;
ffi_call(&cif, (void (*)(void)) func_handle, &result, arg_values);
ml_ret = Val_int(0);
} break;
}
 
freeandfail:
for (i = 0; i < nargs; i++) {
switch (Tag_val(Field(ml_args, i))) {
Line 275 ⟶ 287:
free(arg_values);
free(arg_types);
 
if (ffi_prep_cif_failed)
failwith("ffi_prep_cif");
 
CAMLreturn(ml_ret);
Line 286 ⟶ 301:
Here is the '''"Makefile"''':
 
<lang make>FFI_LIBS := $(shell pkg-config --libs libffi)
<lang make>
FFI_LIBS := $(shell pkg-config --libs libffi)
FFI_CFLAGS := $(shell pkg-config --cflags libffi)
 
Line 330 ⟶ 344:
rm -f *.[oa] *.so *.cm[ixoa] *.cmxa *.opt
</lang>
sed -i "s/ /\t/g" Makefile
 
 
Line 346 ⟶ 361:
| String v -> Printf.printf "ocaml: got (String \"%s\")\n%!" v
| Ptr _ -> Printf.printf "ocaml: got (Ptr)\n%!"
| Void -> Printf.printf "ocaml: got (Void)\n%!"
 
let main1() =
Line 381 ⟶ 397:
let func = dlsym ~lib ~func_name:"func_float_param" in
handle_return(fficall ~func ~args:[| Float 211.7 |] ~return:Return_float);
dlclose ~lib;
;;
 
let main6() =
let lib = dlopen "./fakelib.so" [RTLD_LAZY] in
let func = dlsym ~lib ~func_name:"func_void_param" in
handle_return(fficall ~func ~args:[| |] ~return:Return_void);
dlclose ~lib;
;;
Line 390 ⟶ 413:
print_newline(); main4();
print_newline(); main5();
print_newline(); main6();
;;</lang>
 
Line 447 ⟶ 471:
printf("c: got float (%g)\n", f); fflush(stdout);
return 233.2;
}
 
void func_void_param(void)
{
printf("c: void function\n"); fflush(stdout);
}
</lang>