caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Goswin von Brederlow <goswin-v-b@web.de>
To: caml-list@inria.fr
Subject: Re: [Caml-list] What's the best practice for bindings for c++ templates?
Date: Thu, 30 Jul 2015 20:00:42 +0200	[thread overview]
Message-ID: <20150730180041.GA32510@frosties> (raw)
In-Reply-To: <B604D632D4692C45A95E5EB6E3E0FFF204866B48@DEKOMMBX002.net.plm.eds.com>

On Wed, Jul 29, 2015 at 12:36:53PM +0000, Bauer, Christoph wrote:
> Hi,
> 
> > val make : 'a -> 'a t
> > val swap : 'a t -> 'a -> 'a
> > val get : 'a t -> 'a
> > 1) For the stub code I need to instantiate the template with 'a, which
> > obviously doesn't work since the C++ stub has no idea about what type
> > ocaml will use in the future.
> >
> > So do I instantiate it with void *? uintptr_t? value?
> 
> 1.)  It's value, but I think you ocaml api would need an additional parameter in make to describe the type 'a  (cmp to  float32 in the bigarray library).

Since make gets an initial 'a as argument the type of 'a t should be
clear. No extra parameter needed.
 
> > 2) I'm storing ocaml values in C++ structures and getting them back.
> > How do I make that play nice with the GC?
> 
> My advice: don't do this. It may work for a while but then the GC moves the values and your
> program crashes. It would be better to keep the values in OCaml e.g. in a hashtable and to store the key
> (integer or string) in C++. With callbacks to ocaml, you could define some  setters/getters for the content
> of the value itself. This approach means some overhead, but it should work quite well.
> 
> Sometimes it is also a better idea to make just a copy of OCaml value (std::string(String_val(value))).

Yeah, I've considered that the GC moves values around. So the address
where c++ stores the value has to be added to the GC root set or there
has to be an indirection, like putting the value into a hashtbl like
you suggest. The later I find ugly so I was looking for a better solution.
 
> > 3) I have the option of changing the libraries API as it's not set in stone yet.
> > What would be beneficial to interfacing with ocaml (and maybe python)
> > without making the c++ API to horrible?
> >
> > E.g. Foo could have:
> >
> >     void set_T_destructor(void (*destructor)(T *t));
> >
> > Then ~Foo() would call 'destructor(&t)' to "free" the stored T, which would
> > unregister it from the GC.
> 
> So you need something like this (I omit the template stuff):
> 
> class Bar {
>    ~Bar() {
> // call the custom destructor
>  }
> }
> 
> #define CppBar_val(x) (*((Bar**) Data_custom_val(x)))
> 
> static
> void finalize_cppbar( value v ) {
>    delete CppBar_val(v);
> }
> 
> 
> static struct custom_operations cpp_bar_ops = {
>   "de.web.cpp.bar",
>   finalize_cppbar,
>   custom_compare_default,
>   custom_hash_default,
>   custom_serialize_default,
>   custom_deserialize_default
> };
> 
> 
> static value alloc_cppbar(Bar * bar)
> {
>   value v = alloc_custom(&cpp_bar_ops, sizeof(Bar *), 0, 1);
>   CppBar_val(v) = bar;
>   return v;
> }
> 
> As Xavier Leroy suggested, you could also use a shared_ptr<T> instead of Bar* and call reset() on it in the finalize_cppbar.
> I didn't tried it.
> 
> Regards,
> Christoph Bauer

I don't think you are seeing this the right way around. Your code
would work if Bar was a C++ structure that you want to keep a
reference to from ocaml. But here I need a C++ structure that keeps a
reference to an ocaml value alive.

And it must be destroyed by either ocaml or c++, whichever comes last.
Maybe something more like this (pseudocode):

class ValueHolder {
  ValueHolder(value val) : val_(val) { gc_register_root(&val); }
  ~ValueHolder() { gc_unregister_root(&val); }
  value val_;
};

Now I can store ValueHolder in C++ and the GC will update val_ when it
moves the value around. Probably better to store a
std::shared_ptr<ValueHolder> because otherwise the move and copy
constructors and assignment operators would need to aquire the runtime
lock and update the GC roots too.

Overall still not the brilliant and clean solution I'm hoping to exist
somewhere out there. :(

MfG
	Goswin

      reply	other threads:[~2015-07-30 18:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-28 18:40 Goswin von Brederlow
2015-07-29  9:27 ` Xavier Leroy
2015-07-29 12:36 ` AW: " Bauer, Christoph
2015-07-30 18:00   ` Goswin von Brederlow [this message]

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=20150730180041.GA32510@frosties \
    --to=goswin-v-b@web.de \
    --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).