Version française
Home     About     Download     Resources     Contact us    
Browse thread
Shared libraries with ocamlopt callable from C (without main())?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Ben Jakb <ben.jakb@g...>
Subject: Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?
> Could you point out what problem you faced?

I try to create a static library called "libadd5wrapperlib.a" ( I know
kinda WTF ). So here is my simple example:

(Warning: You'll see a lot of bad code below, sorry for that, I work
hard to improve)

=====  $ cat ./add5.ml =====
    (* the code doesnt add anything yet, it just gives 5 back *)
    let add_five () =
      let i = ref 0 in
        i := 5;
        !i;;
    Callback.register "add five" add_five;;


=====  $ cat ./add5wrapperlib.c (Wraps the Ocaml code ) =====
    #include <stdio.h>
    #include <caml/mlvalues.h>
    #include <caml/callback.h>
    int add5wrapper(char **argv) {
        int add_5;
        caml_startup(argv);
        add_5=Int_val(callback(*caml_named_value("add five"),Val_unit));
        return add_5;
}

=====  $ cat ./include/libadd5wrapper.h (header file) =====
    extern int add5 (char **argv);

=====  $ cat ./main.c =====
    #include <stdio.h>
    #include "libadd5wrapper.h"
    int main (int argc,char **argv){
       printf("Gimme - %d \n", add5wrapper());
       return 0;
}

Now I try to BUILD the whole thing:
----------------------------------------------
# 1.) Build the OCaml code
ocamlopt -output-obj add5.ml -o add5-prog.o

# 2.) Create the static library
gcc -c add5wrapperlib.c
ar rs lib/libadd5wrapperlib.a add5wrapperlib.o

# 3.) Create the main object file
gcc -c main.c -Iinclude -I"`ocamlc -where`"

# 4.) Build the whole thing:
gcc --static -Iinclude -Llib -o mainprog.opt main.o add5wrapperlib.o
-L"`ocamlc -where`" -ladd5wrapperlib -lm -ldl -lasmrun

Number 4 is where it breaks. I get a ton of errors and this is where
it ends for me. Because # 4 is also the point where I definitely have
no idea what I'm doing.
Thanks for helping me.

Errors of #4:
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(startup.o): In function
`caml_main':
startup.c:(.text+0x209): undefined reference to `caml_data_segments'
startup.c:(.text+0x21d): undefined reference to `caml_code_segments'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_ceil_float':
floats.c:(.text+0x225): undefined reference to `ceil'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_atan2_float':
floats.c:(.text+0x24b): undefined reference to `atan2'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_atan_float':
floats.c:(.text+0x268): undefined reference to `atan'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_acos_float':
floats.c:(.text+0x285): undefined reference to `acos'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_asin_float':
floats.c:(.text+0x2a2): undefined reference to `asin'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_tanh_float':
floats.c:(.text+0x2bf): undefined reference to `tanh'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_tan_float':
floats.c:(.text+0x2dc): undefined reference to `tan'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_cosh_float':
floats.c:(.text+0x2f9): undefined reference to `cosh'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_cos_float':
floats.c:(.text+0x316): undefined reference to `cos'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_sinh_float':
floats.c:(.text+0x333): undefined reference to `sinh'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_sin_float':
floats.c:(.text+0x350): undefined reference to `sin'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_power_float':
floats.c:(.text+0x376): undefined reference to `pow'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_sqrt_float':
floats.c:(.text+0x3a6): undefined reference to `sqrt'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_log10_float':
floats.c:(.text+0x487): undefined reference to `log10'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_log_float':
floats.c:(.text+0x4a4): undefined reference to `log'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_fmod_float':
floats.c:(.text+0x599): undefined reference to `fmod'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_floor_float':
floats.c:(.text+0x5b6): undefined reference to `floor'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(floats.o): In function
`caml_exp_float':
floats.c:(.text+0x5d3): undefined reference to `exp'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(unix.o): In function
`caml_dlerror':
unix.c:(.text+0x1db): undefined reference to `dlerror'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(unix.o): In function `caml_dlsym':
unix.c:(.text+0x1f5): undefined reference to `dlsym'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(unix.o): In function
`caml_dlclose':
unix.c:(.text+0x208): undefined reference to `dlclose'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(unix.o): In function
`caml_dlopen':
unix.c:(.text+0x223): undefined reference to `dlopen'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(i386.o): In function
`caml_start_program':
(.text+0x129): undefined reference to `caml_program'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(i386.o): In function
`caml_callback2_exn':
(.text+0x221): undefined reference to `caml_apply2'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(i386.o): In function
`caml_callback3_exn':
(.text+0x241): undefined reference to `caml_apply3'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_array_bound_error':
fail.c:(.text+0x75): undefined reference to `caml_exn_Invalid_argument'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_stack_overflow':
fail.c:(.text+0x98): undefined reference to `caml_bucket_Stack_overflow'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_out_of_memory':
fail.c:(.text+0xaa): undefined reference to `caml_bucket_Out_of_memory'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_sys_error':
fail.c:(.text+0x144): undefined reference to `caml_exn_Sys_error'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_invalid_argument':
fail.c:(.text+0x17d): undefined reference to `caml_exn_Invalid_argument'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_failwith':
fail.c:(.text+0x196): undefined reference to `caml_exn_Failure'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_sys_blocked_io':
fail.c:(.text+0x21a): undefined reference to `caml_exn_Sys_blocked_io'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_not_found':
fail.c:(.text+0x22c): undefined reference to `caml_exn_Not_found'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_zero_divide':
fail.c:(.text+0x23e): undefined reference to `caml_exn_Division_by_zero'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(fail.o): In function
`caml_raise_end_of_file':
fail.c:(.text+0x250): undefined reference to `caml_exn_End_of_file'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): In function
`caml_init_frame_descriptors':
roots.c:(.text+0x118): undefined reference to `caml_frametable'
roots.c:(.text+0x136): undefined reference to `caml_frametable'
roots.c:(.text+0x18f): undefined reference to `caml_frametable'
roots.c:(.text+0x207): undefined reference to `caml_frametable'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): In function
`caml_do_roots':
roots.c:(.text+0x25c): undefined reference to `caml_globals'
roots.c:(.text+0x293): undefined reference to `caml_globals'
/usr/local/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): In function
`caml_oldify_local_roots':
roots.c:(.text+0x364): undefined reference to `caml_globals'
roots.c:(.text+0x36b): undefined reference to `caml_globals'
collect2: ld returned 1 exit status















2009/1/9 Matthieu Dubuget <matthieu.dubuget@gmail.com>:
> Ben Aurel a écrit :
>> I'm thinking about the possibility to use OCaml as an extension
>> language. If I wanted to call a OCaml function from langX I had to use
>> a C wrapper.
>>
>>     langX -> ( C API of langX | C Wrapper | C API of OCaml ) -> OCaml
>>
>
> Yes
>
>> But could somebody tell me if ( and maybe how ) this can be done. I made some attempts, but
>> there is always a main() function involved. But this C wrapper would be a shared library.
>>
>
> Exactly. You can deliver your OCaml code as shared library, and then
> call it from
> any language that can call a shared library.
>
> Could you point out what problem you faced?
>
> Salutations
>
> Matt
>
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>