[Mono-list] Platform invoke for stdarg
Francis Brosnan Blázquez
acinom@bigfoot.com
Tue, 16 Nov 2004 14:13:41 +0100
El lun, 15-11-2004 a las 20:54 -0500, Jonathan Pryor escribió:
> On Mon, 2004-11-15 at 20:24 +0100, Francis Brosnan Blázquez wrote:
> > Hi,
> >
> > I'm trying to do a P/Invoke call for functions such as
> >
> > void Test(int value, ...);
> >
> > But I don't get it working. Is it posible to do a platform invoke for c
> > functions that make use of stdarg api?
>
> No, and Maybe. :-)
>
> There is no general way to marshal "..." parameters, which requires that
> all the parameters be passed on the stack -- the Cdecl calling
> convention. The .NET marshaller can only work with a fixed number of
> arguments.
>
> However, there are two solutions:
>
> 1. Standard overloading: If there is a "reasonable" number of
> parameters you need, you can explicitly specify them as overloads. I do
> this in Mono.Posix to wrap open(2):
>
> DllImport ("libc", CallingConvention=CallingConvention.Cdecl)
> public static extern int open (string pathname, int flags);
>
> DllImport ("libc", CallingConvention=CallingConvention.Cdecl)
> public static extern int open (string pathname, int flags, uint mode);
>
> If you plan on using this code on Windows, you *must* specify
> CallingCOnvention.Cdecl, as the default is Stdcall, which doesn't permit
> variable argument lists.
>
> Obviously, this is only viable if you have a limited number of potential
> overloads. Wrapping printf(3) is impractical, as it could result in
> hundreds (thousands?) of overloads.
>
> 2. Get creative, take an object[] array, and generate some
> System.Reflection.Emit code which accepts the proper number of
> parameters of the proper type, and invoke the recently generated code.
> IIRC cocoa-sharp does something similar to this for its msg_send
> implementation. Pro: it works for any argument list. Con: it's not
> easy.
>
This solution sounds good. Thanks for your clear reply!
> - Jon
>
>
>
--
Francis Brosnan Blázquez <acinom@bigfoot.com>