caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* OCaml/C interface
@ 2007-10-25 22:17 Nathan Mishra Linger
  2007-10-26  9:18 ` [Caml-list] " Julien Moutinho
  0 siblings, 1 reply; 7+ messages in thread
From: Nathan Mishra Linger @ 2007-10-25 22:17 UTC (permalink / raw)
  To: OCaml List

[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]

Having just read Chapter 18 of the manual regarding "Interfacing C with
OCaml", I wrote a simple program to test my understanding.  However, when I
try to compile it I run into some undefined symbol problems (_tgetent,
_tgetnum, etc).  My machine is a PowerPC iBook G4 running OS X 10.4.10.

Does anyone know how to fix this?  After Googling around, I think this is a
Mac problem rather than an OCaml one, but I thought people on this list
might have come up against this same problem.  Also, any comments on my C
code that calls OCaml would be appreciated.

Thanks,
Nathan

==================================
prompt$ cat test.ml

let rec from_to x y = if x > y then [] else x :: from_to (x+1) y
let sum_list xs = List.fold_left (+) 0 xs

let _ = Callback.register "from_to" from_to
let _ = Callback.register "sum_list" sum_list
let _ = Callback.register "gc" Gc.full_major

prompt$ cat test.c
/* C includes */
#include <stdio.h>

/* OCaml includes */
#include "caml/mlvalues.h"
#include "caml/memory.h"
#include "caml/callback.h"

value up_to(int n) {
  CAMLparam0();
  CAMLreturn(caml_callback2(*caml_named_value("from_to"), Val_int(1),
Val_int(n)));
}

void gc(void) {
  caml_callback(*caml_named_value("gc"), Val_unit);
  return;
}

int sum(value xs) {
  CAMLparam1(xs);
  CAMLreturn(Int_val(caml_callback(*caml_named_value("sum_list"), xs)));
}

int main() {
  CAMLlocal1(xs);
  char* argv[]  = {"yo"};
  caml_main(argv);
  xs = up_to(5);
  gc();
  printf("sum of [1..5] = %i\n", sum(xs));
}

prompt$ cat Makefile
all:
        ocamlc -c test.ml
        cc -I/usr/local/lib/ocaml -c test.c
        ocamlc -output-obj -o camlcode.o test.cmo
        cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun

clean:
        rm *.cm? *.o

prompt$ make
ocamlc -c test.ml
cc -I/usr/local/lib/ocaml -c test.c
ocamlc -output-obj -o camlcode.o test.cmo
cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun
/usr/bin/ld: Undefined symbols:
_tgetent
_tgetnum
_tgetstr
_tputs
collect2: ld returned 1 exit status
make: *** [all] Error 1

[-- Attachment #2: Type: text/html, Size: 2757 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-25 22:17 OCaml/C interface Nathan Mishra Linger
@ 2007-10-26  9:18 ` Julien Moutinho
  2007-10-26 18:13   ` Nathan Mishra Linger
  0 siblings, 1 reply; 7+ messages in thread
From: Julien Moutinho @ 2007-10-26  9:18 UTC (permalink / raw)
  To: caml-list

On Thu, Oct 25, 2007 at 03:17:43PM -0700, Nathan Mishra Linger wrote:
> Having just read Chapter 18 of the manual regarding "Interfacing C with
> OCaml", I wrote a simple program to test my understanding.  However, when I
> try to compile it I run into some undefined symbol problems (_tgetent,
> _tgetnum, etc).  My machine is a PowerPC iBook G4 running OS X 10.4.10.
> 
> Does anyone know how to fix this?  After Googling around, I think this is a
> Mac problem rather than an OCaml one, but I thought people on this list
> might have come up against this same problem.  Also, any comments on my C
> code that calls OCaml would be appreciated.

A solution may be:

% ls
Makefile Makefile.old test.c test.c.old test.ml

% diff -U 0 Makefile.old Makefile
--- Makefile.old        2007-10-26 11:07:41.000000000 +0200
+++ Makefile    2007-10-26 11:11:34.000000000 +0200
@@ -5 +5 @@
-       cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun
+       cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun -lm -lcurses

% diff -u test.c.old test.c
--- test.c.old  2007-10-26 11:06:33.000000000 +0200
+++ test.c      2007-10-26 11:02:42.000000000 +0200
@@ -25,9 +25,10 @@
 int main() {
   CAMLlocal1(xs);
   char* argv[]  = {"yo"};
-  caml_main(argv);
+  caml_startup(argv);
   xs = up_to(5);
   gc();
   printf("sum of [1..5] = %i\n", sum(xs));
+  return EXIT_SUCCESS;
 }

% make
ocamlc -c test.ml
cc -I/usr/local/lib/ocaml -c test.c
ocamlc -output-obj -o camlcode.o test.cmo
cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun -lm -lcurses

% ./myprog
sum of [1..5] = 15

HTH,
  Julien.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-26  9:18 ` [Caml-list] " Julien Moutinho
@ 2007-10-26 18:13   ` Nathan Mishra Linger
  2007-10-28 12:36     ` David Teller
  0 siblings, 1 reply; 7+ messages in thread
From: Nathan Mishra Linger @ 2007-10-26 18:13 UTC (permalink / raw)
  To: Julien Moutinho; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1828 bytes --]

On 10/26/07, Julien Moutinho <julien.moutinho@gmail.com> wrote:
>
> On Thu, Oct 25, 2007 at 03:17:43PM -0700, Nathan Mishra Linger wrote:
> > Having just read Chapter 18 of the manual regarding "Interfacing C with
> > OCaml", I wrote a simple program to test my understanding.  However,
> when I
> > try to compile it I run into some undefined symbol problems (_tgetent,
> > _tgetnum, etc).  My machine is a PowerPC iBook G4 running OS X 10.4.10.
> >
> > Does anyone know how to fix this?  After Googling around, I think this
> is a
> > Mac problem rather than an OCaml one, but I thought people on this list
> > might have come up against this same problem.  Also, any comments on my
> C
> > code that calls OCaml would be appreciated.
>
> A solution may be:
>
> % ls
> Makefile Makefile.old test.c test.c.old test.ml
>
> % diff -U 0 Makefile.old Makefile
> --- Makefile.old        2007-10-26 11:07:41.000000000 +0200
> +++ Makefile    2007-10-26 11:11:34.000000000 +0200
> @@ -5 +5 @@
> -       cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun
> +       cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun
> -lm -lcurses
>
> % diff -u test.c.old test.c
> --- test.c.old  2007-10-26 11:06:33.000000000 +0200
> +++ test.c      2007-10-26 11:02:42.000000000 +0200
> @@ -25,9 +25,10 @@
> int main() {
>    CAMLlocal1(xs);
>    char* argv[]  = {"yo"};
> -  caml_main(argv);
> +  caml_startup(argv);
>    xs = up_to(5);
>    gc();
>    printf("sum of [1..5] = %i\n", sum(xs));
> +  return EXIT_SUCCESS;
> }
>
> % make
> ocamlc -c test.ml
> cc -I/usr/local/lib/ocaml -c test.c
> ocamlc -output-obj -o camlcode.o test.cmo
> cc -o myprog test.o camlcode.o -L/usr/local/lib/ocaml -lcamlrun -lm
> -lcurses
>
> % ./myprog
> sum of [1..5] = 15
>
> HTH,
>   Julien.



Yep.  That did it.  Thanks, Julien!

Nathan

[-- Attachment #2: Type: text/html, Size: 2608 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-26 18:13   ` Nathan Mishra Linger
@ 2007-10-28 12:36     ` David Teller
  2007-10-28 13:34       ` skaller
  2007-10-28 13:48       ` Christopher L Conway
  0 siblings, 2 replies; 7+ messages in thread
From: David Teller @ 2007-10-28 12:36 UTC (permalink / raw)
  To: Nathan Mishra Linger; +Cc: Julien Moutinho, caml-list

I'm wondering how hard it would be to write a generic module for calling
C functions without having to write a specific wrapper. Something along
the lines of (with revised syntax)


type c_type = 
 [ TVoid
 | TChar
 | TInt32
 | TInt64
 | ...
 | TStruct  of list c_type
 | TUnion   of list c_type
 | TPointer of c_type
 | TArray   of array c_type
 | TString
 | TWString
 | ...
 | TReclaimable of c_type
 | TNotReclaimable of c_type
 ];

type c_value =
 [ Void
 | TChar of char
 | TInt32 of int32
 | ...
 ];

type t; (*The type of a C function*)

(** 
 Perform a dynamic link with a C function.
 Evalutes to None in case of dynamic linking error.
 *)
value acquire_function : ~name:string -> ~args:list c_type -> option t; 

(**
 Actually perform the call.
*)
value call : t -> ~args:list c_type -> c_type;

value release_value : c_value -> unit;
value release_function : t -> unit;

Etc.

Come to think about it, we could draw some inspiration from Python's 
CTypes [1]. While it wouldn't be as safe as the current manner of
calling C from OCaml, it would be much more convenient at least for
prototyping. Plus, with a little Camlp4, it would make it possible to
write something like

external "C" my_native_function = "char* stuff(char* a, char* b)" 

That was just a random thought, I have no particular interest in
implementing this, but what do you think about it ?

Cheers,
 David

[1] http://docs.python.org/lib/module-ctypes.html


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-28 12:36     ` David Teller
@ 2007-10-28 13:34       ` skaller
  2007-10-28 13:48       ` Christopher L Conway
  1 sibling, 0 replies; 7+ messages in thread
From: skaller @ 2007-10-28 13:34 UTC (permalink / raw)
  To: David Teller; +Cc: Nathan Mishra Linger, caml-list


On Sun, 2007-10-28 at 13:36 +0100, David Teller wrote:

> external "C" my_native_function = "char* stuff(char* a, char* b)" 
> 
> That was just a random thought, I have no particular interest in
> implementing this, but what do you think about it ?

This is the basis of how Felix binds to C/C++.

You need to provide ways to bind *types* as well.

With experience, you'll find various property annotations
are useful.

Felix says stuff like:

	type mytype = "mytype";
	fun f: int * mytype-> int = "f($1,$2)";

and emits appropriate code. Camlp4 can do the same thing
probably, and emit C glue.

Note your form of specification isn't as good as mine.
With coding like my 'f' you specify the name and Ocaml
calling convention, then the way to wrap an Ocaml call
to a C call. In particular you could write:

	fun f: int * mytype-> int = "g($1,100,$2)+1";

The problem with your notation is that it is a bit naive:
it assumes a simple correspondence between Ocaml and C calls
that doesn't exist in general: you need to use a richer
binding language.

The actual C code would make a function which is called
which does conversions based on type stuff for the
arguments $1 $2 etc, and then actually emit the C
code with replacements of the converted values.

You need to allow for more than one kind of conversion.
Concrete copying, as in integers, is not the same as a pointer
based representation (abstract type). It's important not
to fix one or the other but allow choices.

Felix also does this:

	fun f: ... = " .. " requires '#include "mine.h"';

so that you can put the header file etc in with the 
specification.

Once you use automated wrapping, it HAS to do everything
because you can no longer intervene -- the only alternative
is write your C glue by hand in a separate file, which is
precisely what the facility here is trying to avoid.

A good design goal here is .. GET RID OF int64 etc type
from Ocaml. Work on the binding feature until it can
be done by the user with no external C code.


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-28 12:36     ` David Teller
  2007-10-28 13:34       ` skaller
@ 2007-10-28 13:48       ` Christopher L Conway
  2007-10-28 15:39         ` David Teller
  1 sibling, 1 reply; 7+ messages in thread
From: Christopher L Conway @ 2007-10-28 13:48 UTC (permalink / raw)
  To: David Teller; +Cc: Nathan Mishra Linger, caml-list

This is very similar to what you would get from SWIG
(http://www.swig.org/, OCaml support is in SVN): it generates a
binding where each C function has type c_obj -> c_obj, where c_obj is
more or less your c_type. Basically, this just hoists the problem up
one level of abstraction, so that instead of writing C code using
mltypes.h, you write OCaml code that massages effectively untyped
values coming out of the library.

Regards,
Chris

On 10/28/07, David Teller <David.Teller@ens-lyon.org> wrote:
> I'm wondering how hard it would be to write a generic module for calling
> C functions without having to write a specific wrapper. Something along
> the lines of (with revised syntax)
>
>
> type c_type =
>  [ TVoid
>  | TChar
>  | TInt32
>  | TInt64
>  | ...
>  | TStruct  of list c_type
>  | TUnion   of list c_type
>  | TPointer of c_type
>  | TArray   of array c_type
>  | TString
>  | TWString
>  | ...
>  | TReclaimable of c_type
>  | TNotReclaimable of c_type
>  ];
>
> type c_value =
>  [ Void
>  | TChar of char
>  | TInt32 of int32
>  | ...
>  ];
>
> type t; (*The type of a C function*)
>
> (**
>  Perform a dynamic link with a C function.
>  Evalutes to None in case of dynamic linking error.
>  *)
> value acquire_function : ~name:string -> ~args:list c_type -> option t;
>
> (**
>  Actually perform the call.
> *)
> value call : t -> ~args:list c_type -> c_type;
>
> value release_value : c_value -> unit;
> value release_function : t -> unit;
>
> Etc.
>
> Come to think about it, we could draw some inspiration from Python's
> CTypes [1]. While it wouldn't be as safe as the current manner of
> calling C from OCaml, it would be much more convenient at least for
> prototyping. Plus, with a little Camlp4, it would make it possible to
> write something like
>
> external "C" my_native_function = "char* stuff(char* a, char* b)"
>
> That was just a random thought, I have no particular interest in
> implementing this, but what do you think about it ?
>
> Cheers,
>  David
>
> [1] http://docs.python.org/lib/module-ctypes.html
>
> _______________________________________________
> 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
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] OCaml/C interface
  2007-10-28 13:48       ` Christopher L Conway
@ 2007-10-28 15:39         ` David Teller
  0 siblings, 0 replies; 7+ messages in thread
From: David Teller @ 2007-10-28 15:39 UTC (permalink / raw)
  To: Christopher L Conway; +Cc: caml-list

Interesting, thanks.

Cheers,
 David


On Sun, 2007-10-28 at 09:48 -0400, Christopher L Conway wrote:
> This is very similar to what you would get from SWIG
> (http://www.swig.org/, OCaml support is in SVN): it generates a
> binding where each C function has type c_obj -> c_obj, where c_obj is
> more or less your c_type. Basically, this just hoists the problem up
> one level of abstraction, so that instead of writing C code using
> mltypes.h, you write OCaml code that massages effectively untyped
> values coming out of the library.
> 
> Regards,
> Chris


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-10-28 15:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-25 22:17 OCaml/C interface Nathan Mishra Linger
2007-10-26  9:18 ` [Caml-list] " Julien Moutinho
2007-10-26 18:13   ` Nathan Mishra Linger
2007-10-28 12:36     ` David Teller
2007-10-28 13:34       ` skaller
2007-10-28 13:48       ` Christopher L Conway
2007-10-28 15:39         ` David Teller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).