caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Lars Nilsson <lars@cymfony.com>
To: caml-list@inria.fr
Subject: [Caml-list] Ocaml -> C -> Ocaml callback problem
Date: Tue, 19 Nov 2002 16:20:25 -0500	[thread overview]
Message-ID: <15834.43801.889171.453764@gargle.gargle.HOWL> (raw)

Hi all,

I am attempting to make use of a C library from within Ocaml, and am
running into a problem when it gets to callbacks (in the form of Ocaml
-> C -> Ocaml. That is, from Ocaml I call a C function, which in turn
calls back into Ocaml.)

I am including two files (cbtest.ml and cb-helper.ml), that exhibit
the problem I am experiencing (using RedHat Linux 7.2, gcc 2.95.3 and
Ocaml 3.06). These files are not at all related to the library I'm
trying to wrap, but I need to use the library in a similar fashion.

I have tried many variations of the setting of closure_fun and
closure_data in cb-helper.c (using Store_field() and alloc(), etc) but
finally went with the least amount of code to keep it clear as the end
result has been the same no matter what.

Desired result: Concatenate "foo" n times (where n is given on the
command line.)

Observed problem: Although it appears to work for small n (less than
280, say), at some point (in my case it happens to be 287, it may
differ between operating systems and other external factors, possibly)
I get a segmentation fault. At one point during debugging I was using
ocamldebug, and it told me it lost contact with the program while
performing a string concatenation (ultimately in the primitive
"create_string"). I don't believe this to be the problem of course (it
would just be a symptom of a problem, not a problem in itself), but am
more or less positive I'm not satisfying the garbage collector in one
way or another.

Obviously, I'm not terribly interesting in the given string, "foo",
but for the library in question it will correspond to some arbitrary
string (and not the same string for each doit either).

Any response that may point out the error in my ways would be greatly
appreciated.

Regards and thanks in advance,
Lars Nilsson

(*****************)
(*** cbtest.ml ***)
(*****************)

type ('a, 'b) someData =
    Callback of ((string -> 'a -> unit) * 'b)

external register : ('a, 'b) someData -> unit = "helper_register"
external doit : unit -> unit = "helper_doit"

let callback s callbackData =
  callbackData := !callbackData ^ s

let _ =
  let n = try int_of_string Sys.argv.(1) with _ -> 10
  and foo = ref "" in
    register (Callback (callback, foo));
    for i = 1 to n do
      doit ()
    done;
    Printf.printf "%s\n%d\n" !foo (String.length !foo)

/***
 ***  cb-helper.c
 ***/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "memory.h"
#include "mlvalues.h"
#include "callback.h"

static value closure_fun;
static value closure_data;

CAMLprim value helper_register(value data)
{
     CAMLparam1(data);

     if (Wosize_val(data) != 1)
          return Val_unit;

     if (Wosize_val(Field(data, 0)) != 2)
          return Val_unit;

     if (Tag_val(Field(Field(data, 0), 0)) == Closure_tag)
     {
          closure_fun = Field(Field(data, 0), 0);
          register_global_root(&closure_fun);

          closure_data = Field(Field(data, 0), 1);
          register_global_root(&closure_data);
     }
     else
          return Val_unit;

     return Val_unit;
}

CAMLprim value helper_doit()
{
     CAMLparam0();

     callback2(closure_fun, copy_string("foo"), closure_data);

     return Val_unit;
}
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


             reply	other threads:[~2002-11-19 21:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-19 21:20 Lars Nilsson [this message]
2002-11-19 22:16 ` Olivier Andrieu
2002-11-19 22:59   ` Lars Nilsson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15834.43801.889171.453764@gargle.gargle.HOWL \
    --to=lars@cymfony.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).