Eric Blake
2020-Aug-18 13:57 UTC
Re: [Libguestfs] [PATCH nbdkit 1/9] server: Add libnbdkit.so.
On 8/18/20 8:53 AM, Richard W.M. Jones wrote:> On Tue, Aug 18, 2020 at 07:48:43AM -0500, Eric Blake wrote: >>> +extern int nbdkit_main (int argc, char *argv[]); >> >> A bit odd to declare this in a .c; but I don't see any existing >> decent .h to put it in, nor is it worth adding a new one just for >> this. So it is fine right here. > > Yup, better suggestions greatfully accepted, but I couldn't see > anywhere obvious. Maybe internal.h?That would work for me.>> Do we want to export it as _nbdkit_main, to make it obvious that >> plugins shouldn't try calling it? That's cosmetic if you think it >> is worth it. > > I was a bit in two minds about whether this API should be public or > not. Could it be called by other programs? Would it be useful for > other programs? Would that just cause us trouble in future?I'm having a hard time seeing why any other program would want to call it; we assume enough control over our environment that being a library in the context of a larger multi-threaded app will probably violate those assumptions.> > I don't intend to push any of this stuff until the 1.23 development > branch opens.Fair enough. Then I'd better finish up my work on .list_exports, .default_export, and .export_description to get those done before 1.22. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Richard W.M. Jones
2020-Aug-19 10:42 UTC
Re: [Libguestfs] [PATCH nbdkit 1/9] server: Add libnbdkit.so.
I believe after a lot of reading around this topic that it should be possible to call from the plugin DLLs into functions in the EXE. One technique is outlined here: https://stackoverflow.com/a/18147774 The idea above is to use DLLTOOL to generate an "import library" (a static linked library containing stubs which are used to resolve at runtime a list of symbols). Import libraries are a normal part of building DLLs on Windows where you always end up building the .DLL and another .LIB containing these stubs. The unusual thing here is only that we generate the import library against an executable rather than a DLL. This would be the simplest technique to use, but I could not make it work in the end. Generating the import library is fine. The problem is actually that libtool doesn't believe it should be possible to add a static .a file when building a DLL and I couldn't work around that. In any case if we did the above we'd still have to hack every plugin and filter so that it links to the import library. But there's a lower-level technique we could use instead: https://nachtimwald.com/2012/07/15/calling-functions-in-exe-from-plugins-in-windows/ https://stackoverflow.com/questions/770344/visual-c-linking-plugin-dll-against-exe#comment1772764_770374 This is to use GetProcAddress from the plugin (DLL) to get the address of symbols in nbdkit.exe. It works a bit like dlsym. I hacked together a test plugin to try this: static void load (void) { int (*_nbdkit_parse_int) (const char *what, const char *str, int *r) GetProcAddress (GetModuleHandle (NULL), "nbdkit_parse_int"); fprintf (stderr, "nbdkit_parse_int addr = %p\n", _nbdkit_parse_int); void (*_nbdkit_debug) (const char *msg, ...) GetProcAddress (GetModuleHandle (NULL), "nbdkit_debug"); _nbdkit_debug ("calling nbdkit_debug now ..."); } and on loading this plugin into server/nbdkit.exe: nbdkit_parse_int addr = 000000000040BD40 nbdkit: debug: calling nbdkit_debug now ... So it really does work. I'm not quite sure exactly how to integrate this. Perhaps adding some Windows-only code to plugin_init which does the appropriate GetProcAddress calls, initializing some function pointers in the plugin? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Richard W.M. Jones
2020-Aug-19 12:26 UTC
Re: [Libguestfs] [PATCH nbdkit 1/9] server: Add libnbdkit.so.
On Wed, Aug 19, 2020 at 11:42:35AM +0100, Richard W.M. Jones wrote:> In any case if we did the above we'd still have to hack every plugin > and filter so that it links to the import library. But there's a > lower-level technique we could use instead: > > https://nachtimwald.com/2012/07/15/calling-functions-in-exe-from-plugins-in-windows/ > https://stackoverflow.com/questions/770344/visual-c-linking-plugin-dll-against-exe#comment1772764_770374 > > This is to use GetProcAddress from the plugin (DLL) to get the address > of symbols in nbdkit.exe. It works a bit like dlsym. I hacked > together a test plugin to try this: > > static void > load (void) > { > int (*_nbdkit_parse_int) (const char *what, > const char *str, > int *r) > GetProcAddress (GetModuleHandle (NULL), "nbdkit_parse_int"); > fprintf (stderr, "nbdkit_parse_int addr = %p\n", _nbdkit_parse_int); > > void (*_nbdkit_debug) (const char *msg, ...) > GetProcAddress (GetModuleHandle (NULL), "nbdkit_debug"); > _nbdkit_debug ("calling nbdkit_debug now ..."); > } > > and on loading this plugin into server/nbdkit.exe: > > nbdkit_parse_int addr = 000000000040BD40 > nbdkit: debug: calling nbdkit_debug now ... > > So it really does work. > > I'm not quite sure exactly how to integrate this. Perhaps adding some > Windows-only code to plugin_init which does the appropriate > GetProcAddress calls, initializing some function pointers in the > plugin?A note to myself since I've run out of time on this today. This is subtly difficult to make work without a lot of build changes. The problem is we have libraries like common/utils/libutils.a which are used by both the server and the plugins (libutils is not the only one, there are several). Imagine that libutils calls nbdkit_debug. Now inside the server this is a direct call. But inside a plugin or filter, on Windows, this must indirect through a function pointer void (*nbdkit_debug) (char *msg, ...). The only way to make this work is to compile all these libraries twice, once for server usage and once for plugins. This is where the technique of using an import library would be more successful, because it presumably does some kind of fixup at load time. But I couldn't easily get that to work, although I may have a look at it again to see if we can get past the libtool issues. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
Apparently Analagous Threads
- Re: [PATCH nbdkit 1/9] server: Add libnbdkit.so.
- [LLVMdev] LLVM ERROR: Program used external function 'printd' which could not be resolved!
- [PATCH nbdkit 5/9 patch split 2/5] lib: Move code for parsing, passwords and paths into libnbdkit.so.
- Re: [PATCH nbdkit 1/9] server: Add libnbdkit.so.
- Re: [PATCH nbdkit 5/9 patch split 2/5] lib: Move code for parsing, passwords and paths into libnbdkit.so.