Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-11 Thread Xavier Leroy
 =  $ cat ./main.c =
 #include stdio.h
 #include libadd5wrapper.h
 int main (int argc,char **argv){
printf(Gimme - %d \n, add5wrapper());

Should be add5wrapper(argv) -- as gcc's warnings told you.

return 0;
 }
 
 Now I try to BUILD the whole thing:
 [...]
 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.

Two things:

- You're not linking in add5-prog.o as far as I can see

- In static mode, the Unix linker is very picky about the relative
  order of -lxxx arguments on the command-line.  For more information,
  see the Info pages for GNU ld.  You probably don't need -static anyway.

The following works:

ocamlopt -output-obj add5.ml -o add5-prog.o
gcc -I`ocamlc -where` -c add5wrapperlib.c
gcc -c main.c
gcc -o mainprog.opt main.o add5wrapperlib.o add5-prog.o \
   -L`ocamlc -where` -lasmrun -ldl -lm

Add -static to the last line if you know you really need it.

Hope this puts you back on tracks.

- Xavier Leroy

___
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


Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-10 Thread Matthieu Dubuget
Ben Jakb a écrit :
 I try to create a static library called libadd5wrapperlib.a ( I know
 kinda WTF ). So here is my simple example:

I did not succeed (yet ;-) ) in making a static library…
I have an example with a shared one, though.

 
 (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;;

I wrote :

Callback.register add five (fun () - 5)


 
 
 =  $ cat ./add5wrapperlib.c (Wraps the Ocaml code ) =
 #include stdio.h
 #include caml/mlvalues.h
 #include caml/callback.h
#include assert.h

#define CAMLCBK_INIT( callback, cbk_name) \
static value *callback = NULL; \
if (callback == NULL) callback = \
  caml_named_value(cbk_name);\
  assert(callback);

static int init_done = 0;

void init_lib(void){
  char *vide[1];
  vide[0] = NULL;
  if (!init_done){
caml_startup(vide);
init_done = 1;
  }
}

int add5wrapper(){
  CAMLCBK_INIT(cbk, add_five);
  return (Int_val ( caml_callback(*cbk, Val_unit)));
}


 =  $ cat ./include/libadd5wrapper.h (header file) =
extern void init_lib(void);
extern int add5wrapper(void);
 
 =  $ cat ./main.c =
 #include stdio.h
 #include libadd5wrapper.h
 int main (int argc,char **argv){
init_lib();
printf(Gimme - %d \n, add5wrapper());
return 0;
 }
 
 Now I try to BUILD the whole thing:
 --

ocamlopt -c add5.ml
ocamlopt -c add5wrapperlib.c
ocamlopt -o add5lib.native.so -ccopt -shared add5.cmx add5wrapperlib.o

ocamlc.opt -ccopt -Iinclude -c main.c
gcc -o maintest.native main.o -l:add5lib.native.so -L. -Wl,-rpath=.

In fact, i used ocamlbuild.


--myocamlbuild.ml -
open Ocamlbuild_plugin
open Command
open Outcome

(* properties as (string * string) list read from ocamlc -config *)
let my_ocamlc_config =
  let rec sc s h =
Scanf.sscanf s %s@: %...@\n%n
  begin fun k v n-
let h' = (k, v) :: h in
let len = String.length s in
  if
len - n = 0
  then
h'
  else
sc (String.sub s n (len - n)) h'
  end in
sc (Ocamlbuild_pack.My_unix.run_and_read ocamlc -config) []

let ext_o = List.assoc ext_obj my_ocamlc_config
let ext_so = List.assoc ext_dll my_ocamlc_config
let syst = List.assoc system my_ocamlc_config

let split s ch =
  let x = ref [] in
  let rec go s =
let pos = String.index s ch in
  x := (String.before s pos)::!x;
  go (String.after s (pos + 1))
  in
try
  go s
with Not_found - !x

exception Found of string

let pwd () =
  let env = Array.to_list (Unix.environment ()) in
  let rec search = function
  [] - 
| h :: tl -
try
  Scanf.sscanf h PWD=%s (fun x - x)
with
_ - search tl in
search env

let split_nl s = split s '\n'

let before_space s =
  try
String.before s (String.index s ' ')
  with Not_found - s

let uncap_module_path p =
  (Pathname.dirname p) / (String.uncapitalize (Pathname.basename p))

let _ = dispatch begin function
  | After_rules -
  if syst = linux_elf then
flag [link; cmldll]  (S[A-ccopt;A-shared])  
  else if syst = mingw then begin
flag [link;cmldll] (S[A-output-obj])
  end;

  flag [cmldll;link;byte] (S[A-custom]);

  rule Mixed C-Ocaml native DLL: cmldll  o*  cmx* - native DLL
(.dll | .so)
~dep:%.cmldll
~prod:(%.native ^ ext_so)
begin
  fun env build -
let output = env (%.native ^ ext_so)
and input = env %.cmldll in
let dir = Pathname.dirname input in

(* TODO: use functions of Pathname module? *)
let ext_o_files, moduls_files =
  string_list_of_file input |
  List.partition (fun fic - 
Filename.check_suffix fic .o) in
let objs = ext_o_files |
List.map Filename.chop_extension |
List.map (fun fic - fic ^ ext_o) in
let cmxs = moduls_files |
List.map (fun modul -
(uncap_module_path 
modul) -.- cmx) in
let deps = cmxs @ objs in

  List.iter ignore_good
(build (List.map (fun x - [dir/x]) deps));


Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-10 Thread Matthieu Dubuget
Ben Jakb a écrit :
 matthieu,
 thanks for the interesting answer.
 Unfortunately I can't build 'mycamlbuild.ml', and it is a bit too
 advanced for me to understand.

If you have a  3.10 version of ocaml, you don't need to compile
yourself myocamlbuild.ml.

This is done automatically by ocamlbuild.

 
 Therefore I'll first go with your standard build commands. So - after
 modifing the sources according to your suggestions I run:
 
 BUILD
 ocamlopt -c add5.ml
 ocamlopt -c add5wrapperlib.c
 ocamlopt -o add5lib.native.so -ccopt -shared add5.cmx add5wrapperlib.o
 ocamlc.opt -ccopt -Iinclude -c main.c
 gcc -o maintest.native main.o -l:add5lib.native.so -L. -Wl,-rpath=.
 
 EXECUTION
 cp add5lib.native.so  lib/
 ./maintest.native
 
 ERROR
 maintest.native: add5wrapperlib.c:24: add5wrapper: Assertion `cbk' failed.
 Aborted
 
 This is the referenced line:
 
 $ sed -n 24p add5wrapperlib.c
 CAMLCBK_INIT(cbk, add_five);
 
 
 Any ideas what' wrong here?

Yes ;-)

This is exactly why i use assert there.

I introduced a bug: the string in the C file is add_five, while the
registered one in the ml file is add five.


Hope this helps

___
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


Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-10 Thread Ben Jakb
 I introduced a bug: the string in the C file is add_five, while the
 registered one in the ml file is add five.

Touché. I suppose I looked to long to this code
And yes it works now, thanks ...

2009/1/10 Matthieu Dubuget matthieu.dubu...@gmail.com:
 Ben Jakb a écrit :
 matthieu,
 thanks for the interesting answer.
 Unfortunately I can't build 'mycamlbuild.ml', and it is a bit too
 advanced for me to understand.

 If you have a  3.10 version of ocaml, you don't need to compile
 yourself myocamlbuild.ml.

 This is done automatically by ocamlbuild.


 Therefore I'll first go with your standard build commands. So - after
 modifing the sources according to your suggestions I run:

 BUILD
 ocamlopt -c add5.ml
 ocamlopt -c add5wrapperlib.c
 ocamlopt -o add5lib.native.so -ccopt -shared add5.cmx add5wrapperlib.o
 ocamlc.opt -ccopt -Iinclude -c main.c
 gcc -o maintest.native main.o -l:add5lib.native.so -L. -Wl,-rpath=.

 EXECUTION
 cp add5lib.native.so  lib/
 ./maintest.native

 ERROR
 maintest.native: add5wrapperlib.c:24: add5wrapper: Assertion `cbk' failed.
 Aborted

 This is the referenced line:

 $ sed -n 24p add5wrapperlib.c
 CAMLCBK_INIT(cbk, add_five);


 Any ideas what' wrong here?

 Yes ;-)

 This is exactly why i use assert there.

 I introduced a bug: the string in the C file is add_five, while the
 registered one in the ml file is add five.


 Hope this helps


___
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


Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-09 Thread Matthieu Dubuget
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


RE: [Caml-list] Shared libraries with ocamlopt callable from C(without main())?

2009-01-09 Thread RABIH.ELCHAAR
The simplest way of achieving what you want might be the following:
1) Write the ocaml code you want to call.
2) register your caml functions via Callback.register
3) In your C code, define the callback values for each ocaml function, via a 
macro like
#define ACTION(actionname)   \
static value *actionname##_closure = NULL;
and fore each c function that wraps the caml call, call 
ACTION(camlfunctionname) before your c wrapping code.
4) define an initialization helper (to get the pointers to ocaml functions), 
something like
#define INITACTION(actionname) \
actionname##_closure = caml_named_value(#actionname);
5) In your DLLMain function, you can have something like
BOOL APIENTRY DllMain(HANDLE module, DWORD reason, void *reserved)
{
  char * argv[2];
  switch (reason) {
  case DLL_PROCESS_ATTACH:
argv[0] = --;
argv[1] = NULL;
caml_startup(argv);
INITACTION(analyze)
INITACTION(updateBlob)
.
break;
  }
  return TRUE;
} 

This handles the C functions:(C Wrapper | C API of OCaml ) - OCaml defining a 
C dll with the needed entries.

You can use afterwards your langX - ( C API of langX - call above dll).
If your langX can call directly C functions without the need of type 
conversions, this can do.
If not, this approach might give you two dlls (langX - C dll) and (C - ocaml) 
dll.

If you want only one dll, I think this is only a linking issue, and can be 
solved by inputing the C-ocaml , compiled ocaml and langX-C together to the 
linker.

Hope this helps,

Sincerely,
Rabih Chaar

-Message d'origine-
De : caml-list-boun...@yquem.inria.fr [mailto:caml-list-boun...@yquem.inria.fr] 
De la part de Matthieu Dubuget
Envoyé : vendredi 9 janvier 2009 09:22
À : caml-l...@inria.fr
Objet : Re: [Caml-list] Shared libraries with ocamlopt callable from C(without 
main())?

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
This message and any attachments (the message) are confidential, intended 
solely for the addressee(s), and may contain legally privileged information. 
Any unauthorised use or dissemination is prohibited. 
E-mails are susceptible to alteration. 
Neither Societe Generale Asset Management nor any of its subsidiaries or 
affiliates shall be liable for the message if altered, changed or falsified. 
  
Find out more about Societe Generale Asset Management's proposal on www.sgam.com
  
 
  
Ce message et toutes les pieces jointes (ci-apres le message) sont 
confidentiels et susceptibles de contenir des informations couvertes par le 
secret professionnel.
Ce message est etabli a l'intention exclusive de ses destinataires.
Toute utilisation ou diffusion non autorisee est interdite. 
Tout message electronique est susceptible d'alteration. Societe Generale Asset 
Management et ses filiales declinent toute responsabilite au titre de ce 
message s'il a ete altere, deforme ou falsifie. 

Decouvrez l'offre et les services de Societe Generale Asset Management sur le 
site www.sgam.fr

___
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


Re: [Caml-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-09 Thread Ben Jakb
 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-list] Shared libraries with ocamlopt callable from C (without main())?

2009-01-08 Thread Ben Aurel
hi
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

Maybe I make it more complicated than it is. 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.

Thanks in advance
ben

___
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