* [Caml-list] Callback in DLL @ 2001-12-26 18:42 Warp 2001-12-28 8:49 ` Xavier Leroy 0 siblings, 1 reply; 4+ messages in thread From: Warp @ 2001-12-26 18:42 UTC (permalink / raw) To: OCaml Hello I got some problems passing a callback function value to a DLL, which will call the caml function when some event occurs. In fact, to use the callback_exn C API function, I have to link with the libcamlrun library, but that's not why I want to do because an interpreter ocamlrun ) is already running. Here's a proposal to resolve such a problem : a DLL should have an EntryPoint ( called CamlEntryPoint for exemple ) and when it's first load by the run-time system, it call the DLL EntryPoint function, passing both cprims and names_of_cprims arrays as parameters. Then we only have to add a "caml" callback func (useless in caml !) to enable DLL callback. I don't know how LabTk works... I'll have a look at it. Warp ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Callback in DLL 2001-12-26 18:42 [Caml-list] Callback in DLL Warp @ 2001-12-28 8:49 ` Xavier Leroy 2001-12-28 12:55 ` Warp 0 siblings, 1 reply; 4+ messages in thread From: Xavier Leroy @ 2001-12-28 8:49 UTC (permalink / raw) To: Warp; +Cc: OCaml > I got some problems passing a callback function value to a DLL, which will > call the caml function when some event occurs. > In fact, to use the callback_exn C API function, I have to link with the > libcamlrun library, but that's not why I want to do because an interpreter > ocamlrun ) is already running. If you're building a DLL whose purpose is to be loaded inside ocamlrun, then you should link with ocamlrun.lib, which is an "import library" around the DLL entry points exported by ocamlrun. > Here's a proposal to resolve such a problem : > a DLL should have an EntryPoint ( called CamlEntryPoint for exemple ) and > when it's first load by the run-time system, it call the DLL EntryPoint > function, passing both cprims and names_of_cprims arrays as parameters. Then > we only have to add a "caml" callback func (useless in caml !) to enable DLL > callback. There are many more functions (and global variables) from the runtime system that need to be known to the DLL. The import library solution is a lot easier, especially since the source code of the DLL can also be compiled as a statically-linked library for use with ocamlc -custom. > I don't know how LabTk works... I'll have a look at it. Good idea. You may want to start with a simpler example, e.g. otherlibs/str/Makefile.nt in the OCaml sources. On to your other questions: > I got some trouble with the garbage collector. > I manage to make callbacks from my dynamic linked library, passing it > the callbackN_exn C API function address when it loads. > Now i'm doing theses things : > [Store a Caml value as a window data] > So , the user got the ' v ' caml value which mainly contains the real handle > of the window and the callback. > And the window itself can obtain ' v ' from handle by calling > etWindowData( handle_of_window ); > in the window proc I'm getting that ' v ' data like that and then I'm > calling caml callback. > All it's fine, but after 10 seconds, the garbage collector collects my ' v ' > data ( I can see that the Tag_val is set to Zero ). Of course. You didn't tell it that you've kept a pointer to "v" in the window data. So, as far as the GC is concerned, nobody is pointing to "v", so it can be freed. > How can i prevent that ? > Shall I use CAMLparamX and other garbage-living-in-harmony-stuff ? Yes, you definitely need to learn how to "live in harmony" with the GC :-) Here, CAMLparamX isn't what you need, because "v" isn't local to the C function. You need to use register_global_root(). If you cannot get the memory address where SetWindowData stores its window data, you'll need to put an additional indirection through a malloc()-ed block. > Theses macros are using local_root so do I have to make my library ask the > current local_root from the interpreter ? The import library takes care of all that. - Xavier Leroy ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Callback in DLL 2001-12-28 8:49 ` Xavier Leroy @ 2001-12-28 12:55 ` Warp 2002-01-03 14:34 ` Xavier Leroy 0 siblings, 1 reply; 4+ messages in thread From: Warp @ 2001-12-28 12:55 UTC (permalink / raw) To: Xavier Leroy; +Cc: OCaml > > I got some problems passing a callback function value to a DLL, which will > > call the caml function when some event occurs. > > In fact, to use the callback_exn C API function, I have to link with the > > libcamlrun library, but that's not why I want to do because an interpreter > > ocamlrun ) is already running. > > If you're building a DLL whose purpose is to be loaded inside > ocamlrun, then you should link with ocamlrun.lib, which is an "import > library" around the DLL entry points exported by ocamlrun. oups ! I didn't see that one ! Ok, lets try.... 1) if I only link ocamlrun.lib, it can't find external "local_roots" needed in CAMLparamX, so I have to use my caml_init_func (dll entry point) and a modified interpreter which call the entry point passing the adress of local_roots. 2) ... and then, my first call to "alloc" is causing a crash inside ocamlrun.lib ( perhaps my modified interpreter is not exporting the function ). More infos : - I got a DLL called camlwlib , which is a modified byterun , adding init calls for dynamic linked libraries and also a Caml_Run exported function which load a bytecode file and run it. - I got a ocamlwrun.exe which only load the camlwlib and call Caml_Run with the first argument - I got my DLL called dllwin32ui - All of theses are build under VC++6 > > Here's a proposal to resolve such a problem : > > a DLL should have an EntryPoint ( called CamlEntryPoint for exemple ) and > > when it's first load by the run-time system, it call the DLL EntryPoint > > function, passing both cprims and names_of_cprims arrays as parameters. Then > > we only have to add a "caml" callback func (useless in caml !) to enable DLL > > callback. > > There are many more functions (and global variables) from the runtime > system that need to be known to the DLL. The import library solution > is a lot easier, especially since the source code of the DLL can also > be compiled as a statically-linked library for use with ocamlc -custom. Without local_roots, perhaps I only need to link ocamlrun.lib and remove my CAMLparam / local / return Macros ? > > I don't know how LabTk works... I'll have a look at it. > > Good idea. You may want to start with a simpler example, e.g. > otherlibs/str/Makefile.nt in the OCaml sources. > > On to your other questions: > > > I got some trouble with the garbage collector. > > I manage to make callbacks from my dynamic linked library, passing it > > the callbackN_exn C API function address when it loads. > > Now i'm doing theses things : > > [Store a Caml value as a window data] > > So , the user got the ' v ' caml value which mainly contains the real handle > > of the window and the callback. > > And the window itself can obtain ' v ' from handle by calling > > etWindowData( handle_of_window ); > > in the window proc I'm getting that ' v ' data like that and then I'm > > calling caml callback. > > All it's fine, but after 10 seconds, the garbage collector collects my ' v ' > > data ( I can see that the Tag_val is set to Zero ). > > Of course. You didn't tell it that you've kept a pointer to "v" in > the window data. So, as far as the GC is concerned, nobody is > pointing to "v", so it can be freed. Actually , "v" is returned to the caml, and then let-stored. So it is referenced. > > How can i prevent that ? > > Shall I use CAMLparamX and other garbage-living-in-harmony-stuff ? > > Yes, you definitely need to learn how to "live in harmony" with the GC :-) > > Here, CAMLparamX isn't what you need, because "v" isn't local to the C > function. You need to use register_global_root(). > > If you cannot get the memory address where SetWindowData stores its > window data, you'll need to put an additional indirection through a > malloc()-ed block. I'll try this.... > > Theses macros are using local_root so do I have to make my library ask the > > current local_root from the interpreter ? > > The import library takes care of all that. "unresolved external symbol _local_roots" ---- Thanks a lot, I'll try at least to *bug* in harmony with the GC :) Warp ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Callback in DLL 2001-12-28 12:55 ` Warp @ 2002-01-03 14:34 ` Xavier Leroy 0 siblings, 0 replies; 4+ messages in thread From: Xavier Leroy @ 2002-01-03 14:34 UTC (permalink / raw) To: Warp; +Cc: OCaml > > If you're building a DLL whose purpose is to be loaded inside > > ocamlrun, then you should link with ocamlrun.lib, which is an "import > > library" around the DLL entry points exported by ocamlrun. > > 1) if I only link ocamlrun.lib, it can't find external "local_roots" needed > in CAMLparamX You probably forgot to compile your C code with the /MD flag (meaning "multithreaded DLL"). Explanation: the Win32 dynamic linker cannot cope with shared global variables, so these need to be accessed by calls to shared functions. The C compiler generates the calls provided the global variable is declared "dllimport". The Caml header files add the proper declaration provided the _DLL symbol is defined. The C compiler defines _DLL if it is invoked with the /MD flag. End of inference :-) > so I have to use my caml_init_func (dll entry point) and a modified > interpreter > which call the entry point passing the adress of local_roots. No you don't have to modify anything. Just read carefully the makefiles in the system sources and follow what's done there. > > Of course. You didn't tell it that you've kept a pointer to "v" in > > the window data. So, as far as the GC is concerned, nobody is > > pointing to "v", so it can be freed. > > Actually , "v" is returned to the caml, and then let-stored. So it is > referenced. All right, but the GC also moves live blocks around, so it really needs to know all the pointers to the block. - Xavier Leroy ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2002-01-03 14:34 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-12-26 18:42 [Caml-list] Callback in DLL Warp 2001-12-28 8:49 ` Xavier Leroy 2001-12-28 12:55 ` Warp 2002-01-03 14:34 ` Xavier Leroy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox