Version française
Home     About     Download     Resources     Contact us    
Browse thread
Calling OCaml from C - nothing shown on stdout
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: David Allsopp <dra-news@m...>
Subject: RE: [Caml-list] Calling OCaml from C - nothing shown on stdout
Andreas Sommer wrote:
> Hi everybody,
>
> I'm trying to call a OCaml function from C code. This is the OCaml file:
> open Printf
>
> let hello () =
>    Printf.fprintf stdout "%s" "test"
>    
> let () =
>    let oc = open_out "/tmp/testfile" in
>    Printf.fprintf oc "test";
>    close_out oc;
>    
>    Printf.fprintf stdout "Caml main function\n";
>    
>    Callback.register "Hello callback" hello;
>    
>    Printf.fprintf stdout "%s" "Finished with OCaml initialization"
>;;

A couple of observations on your coding style - you open Printf and then proceed to use qualified Printf.fprintf calls. There's no need for the open statement. Printf.printf is a shorthand for "Printf.fprintf stdout" which makes the code a bit clearer if you're skimming through it (as Printf.fprintf at a glance looks like actual file I/O rather than channel I/O).

> and this is the C file:
<snip>

As far as I can tell from the manual, there's no particular difference in native code between using caml_main and caml_startup. Your problem is the buffering of stdout in the OCaml runtime. There are two ways of working around this:

1. Allow the runtime to exit using Pervasives.exit at some point on the ML side (or call caml_sys_exit directly in your C code but I haven't tried that...). For example, if I added [; exit 0] to the end of your hello ML function then I get the lines from the Printf calls on the ML side, but out of order (all of the OCaml ones come at the end after the C ones)

2. Insert a flush stdout statement after each Printf.printf call. Better, create another function using Printf.kprintf which flushes stdout each time:
    let flushed_printf x = Printf.kprintf (fun s -> print_string s; flush stdout) in
    flushed_printf "%s" "Finished with..."


David