It looks like this callback pattern does not use recursion through this/self, but is only one standard way to build closures and callbacks. The most natural way to expose this to OCaml would be to allow the OCaml programmer to simply use a first-class function instead of this callback. I see two possible solutions:
(1) You could define, on the C++ side, a generic GenericAdmCallbacks class whose constructor would take as parameter a function pointer implementing Alert (so the function itself only does the plumbing). Then you can expose this class as an OCaml abstract type, and wrap its constructor to expose it to OCaml, so that it takes ocaml-land callbacks and return the abstract type. You can then expose to OCaml your function manipulating AdmCallbacks (let's call it "call_me_later"). So you would have an OCaml interface like this let callback : abstract_admcallbacks = amdcallback (fun p_info p_context ai_code -> ...) call_me_later callback (2) You can put that wrapping logic in the wrapper for call_me_later directly (take an ocaml function, builds the GenericAdmCallbacks, and pass it to the underlying C++ function) call_me_later (fun p_info p_context ai_code -> ....) If the AmdCallbacks interface really is as simple as you've shown, the latter technique is the most convenient. If callbacks have a richer interface (eg. your C++ API expose functions to build callbacks from other callbacks), you'll need a type to speak about callbacks, so the first option is better. (I think I'd go for (1): you can still re-wrap amdcallback into a more convenient form on the ocaml-land, so that you have as little wrapping logic as possible in the unsafe C++ wrapping layer.) On Thu, May 3, 2012 at 3:56 PM, Joel Reymont <joe...@gmail.com> wrote: > Say I have a library class AdmCallbacks > > class AdmCallbacks > { > public : > AdmCallbacks(); > virtual ~AdmCallbacks(); > > /* ---------------------------------------------------------------- */ > > virtual int Alert(AlertInfo * pInfo, > void * pContext, > int * aiCode) = 0; > > private : > }; > > I subclass it and implement the Alert method to receive notifications. > > I then create an instance of my derived class and pass it to some > initialization function so that the API knows to call the methods of > my instance. > > My derived class may look like this > > class MyAdmCallbacks: public AdmCallbacks > { > public : > MyAdmCallbacks() {}; > ~MyAdmCallbacks() {}; > > /* ---------------------------------------------------------------- */ > > virtual int Alert(AlertInfo * pInfo, > void * pContext, > int * aiCode); > }; > > int MyAdmCallbacks::Alert(AlertInfo * pInfo, > void * pContext, > int * aiCode) > { > int iIgnored; > > /* ---------------------------------------------------------------- */ > > cout << endl << endl; > if (!pInfo -> dump(&iIgnored)) > { > cout << "error in pInfo -> dump : " << iIgnored << endl; > } > > /* ---------------------------------------------------------------- */ > > *aiCode = API_OK; > return (OK); > } > > Now, suppose I want to implement the derived class on the OCaml side. > > What is the best way to do it? > > I can derive on the C++ side, keep a pointer to the OCaml instance > (self) in a member variable, instantiate MyAdmCallbacks in the > "MyAdmCallbacks_new" stub function which takes the OCaml self and then > set the member variable. > > The Alert method on the C++ side would then dispatch to OCaml using > the stored OCaml self to call the Alert method as per 18.3.5 of the > manual > > callback(caml_get_public_method(foo, hash_variant("bar")), foo); > > Is there a better way to implement this on the OCaml side? > > Thanks, Joel > > -------------------------------------------------------------------------- > Working on AlgoKit, a new algorithmic trading platform using Rithmic R|API > ---------------------+------------+--------------------------------------- > http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont > ---------------------+------------+--------------------------------------- > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs