From: Pascal Brisset <Pascal.Brisset@wanadoo.fr>
To: Thierry Bravier <thierry.bravier@dassault-aviation.fr>
Cc: caml-list@inria.fr
Subject: Re: problem with ocamlmktop (contd)
Date: Fri, 30 Oct 1998 18:56:38 +0100 (MET) [thread overview]
Message-ID: <13881.64982.392952.452261@whynot> (raw)
In-Reply-To: <13881.37437.266875.483207@lsun162>
[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]
Here is a more complete example demonstrating:
(1) destructors of global objects being called correctly on exit;
(2) translation of C++ exceptions to Caml exceptions;
(3) catching a C++ exception generated by a C++ primitive called
through a Caml callback.
The only trick is that if you really need (3), you have to modify
libcamlrun.a (found in ocaml-1.07/byterun) as follows:
- Insert `extern "C" {' at the beginning of interp.c and callback.c
- Insert `}' at the end of interp.c and callback.c
- Compile interp.c and callback.c with g++ (This will add
".eh_frame" sections which are required for exceptions handling):
g++ -O -fno-defer-pop -Wall -c interp.c -o interp.o
g++ -O -fno-defer-pop -Wall -c callback.c -o callback.o
- Compile everything else normally (make libcamlrun.a)
The Makefile assumes that the modified libcamlrun.a is in
/tmp/ocaml-1.07/byterun/. This was tested with ocaml-1.07 and
g++-2.8.1. Again, things seem to have improved a lot since gcc-2.7.
- Pascal Brisset <pascal.brisset@cnet.francetelecom.fr> +33296051928 -
- France Telecom CNET DTL/MSV | 2 av Pierre Marzin | F-22307 Lannion -
[-- Attachment #2: Makefile --]
[-- Type: text/plain, Size: 271 bytes --]
LIBCAMLRUN=-cclib /tmp/ocaml-1.07/byterun/libcamlrun.a
run:
g++ -I/usr/local/lib/ocaml -c libcell.C
g++ -I/usr/local/lib/ocaml -c mlcell.C
ocamlc -custom libcell.o mlcell.o cell.ml -o cell.out $(LIBCAMLRUN)
./cell.out
clean:
/bin/rm -f *.out *.o *.cm[io] *~ \#*\#
[-- Attachment #3: cell.ml --]
[-- Type: text/plain, Size: 963 bytes --]
module Cell = struct
type t
external global : unit -> t = "caml_global_cell"
external create : int -> t = "caml_cell_create"
external set : t -> int -> unit = "caml_cell_set"
external get : t -> int = "caml_cell_get"
external throw : unit -> string = "caml_cell_throw"
external call : string -> string = "caml_cell_call"
end
let test_cell c =
Printf.printf "c=%d\n" (Cell.get c); flush stdout;
Printf.printf "set 42... "; flush stdout;
Cell.set c 42;
Printf.printf "c=%d\n" (Cell.get c); flush stdout;
begin try
Printf.printf "set -1... "; flush stdout;
Cell.set c (-1);
with e -> print_endline (Printexc.to_string e); flush stdout
end
let _ =
print_endline "start"; flush stdout;
test_cell (Cell.create 271828);
Gc.full_major (); print_newline ();
test_cell (Cell.global ()); print_newline ()
let _ =
Callback.register "caml-throw" Cell.throw;
print_endline ("callback: "^Cell.call "caml-throw"); flush stdout
[-- Attachment #4: libcell.C --]
[-- Type: text/plain, Size: 345 bytes --]
#include <stdio.h>
#include "libcell.h"
Exc::Exc(const char *m) : msg(m) { }
Cell::Cell(int init) : val(init) { printf("init %p=%d\n", this, init); }
Cell::~Cell() { printf("free %p (was %d)\n", this, val); }
void Cell::set(int x) {
if ( x < 0 ) throw Exc("< 0");
val = x;
}
int Cell::get() { return val; }
Cell global_cell(3141592);
[-- Attachment #5: libcell.h --]
[-- Type: text/plain, Size: 189 bytes --]
class Exc {
public:
Exc(const char *m);
const char *msg;
};
class Cell {
public:
Cell(int);
~Cell();
void set(int);
int get();
private:
int val;
};
extern Cell global_cell;
[-- Attachment #6: mlcell.C --]
[-- Type: text/plain, Size: 1182 bytes --]
#include <stdio.h>
extern "C" {
# include <caml/mlvalues.h>
# include <caml/alloc.h>
# include <caml/callback.h>
extern void failwith(char *s);
}
#include "libcell.h"
typedef struct {
final_fun f;
Cell *c;
} mlcell;
static void free_cell(value mlc) {
delete ((mlcell*)mlc)->c;
}
static mlcell mlglobal_cell = { free_cell, &global_cell };
extern "C" value caml_global_cell(value) {
return (value)&mlglobal_cell;
}
extern "C" value caml_cell_create(value mlv) {
value res = alloc_final(sizeof(mlcell)/sizeof(value),
free_cell, 1, 1000); /* ? */
((mlcell*)res)->c = new Cell(Int_val(mlv));
return res;
}
extern "C" value caml_cell_set(value mlc, value mlv) {
try { ((mlcell*)mlc)->c->set(Int_val(mlv)); }
catch (Exc e) { failwith((char*)e.msg); }
return Val_unit;
}
extern "C" value caml_cell_get(value mlc) {
int v = ((mlcell*)mlc)->c->get();
return Val_int(v);
}
extern "C" value caml_cell_throw(value) {
throw Exc("caml_cell_throw");
}
extern "C" value caml_cell_call(value mlname) {
value f = *caml_named_value(String_val(mlname));
try { return callback(f, Val_unit); }
catch (Exc e) { return copy_string((char*)e.msg); }
}
next prev parent reply other threads:[~1998-10-30 19:00 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
1998-10-14 16:47 problem with ocamlmktop -output-obj Thierry Bravier
1998-10-15 17:22 ` Xavier Leroy
1998-10-16 10:40 ` Thierry Bravier
1998-10-26 16:03 ` Thierry Bravier
1998-10-30 10:17 ` Pascal Brisset
1998-10-30 17:56 ` Pascal Brisset [this message]
1998-11-03 9:32 ` problem with ocamlmktop (contd) Pascal Brisset
1998-11-04 17:56 ` Thierry Bravier
1998-11-04 16:12 ` problem with ocamlmktop -output-obj luther
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=13881.64982.392952.452261@whynot \
--to=pascal.brisset@wanadoo.fr \
--cc=caml-list@inria.fr \
--cc=thierry.bravier@dassault-aviation.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