[Mono-list] Multiplatform DllImport?

Rhys Weatherley rweather@zip.com.au
Sat, 24 Nov 2001 09:47:51 +1000


Miguel de Icaza wrote:

> >   How are we supposed to be dealing with classes which offer platform
> > services (e.g. System.Net.Sockets.Socket)? This class will need to
> > import not only things like socket, bind, listen, connect, but also
> > Win32 (Winsock) functions like WSAStartup and WSACleanup. I hate to
> > ask before looking so...
>
> At least on the Unix side of things we should be doing that using the
> wrapper code in mono/mono/wrapper and maybe also for Windows
> compatibility (this makes sure that enumeration constants from the
> underlying OS are mapped correctly).

As another data point, I recently had to address the problem
of "same function name, different library" that is common
on Unix platforms for Portable.NET.  e.g. "listen" living in
"libc" on some platforms, and "libsocket" on others.

Instead of having a separate .cs file for every platform
to import the definition using PInvoke, I introduced a private
attribute called "DllImportMap".  e.g.

[DllImportMap("winsock.dll", "*-sunos-*", "libsocket.so")]
[DllImportMap("winsock.dll", "std-shared-object", "libc.so")]
class SocketOps
{
    [DllImport("winsock.dll")]
    public int listen(int fd, int backlog);
}

This specifies that "winsock.dll" is the default if all
the engine knows about is Windows (e.g. Microsoft's).
It then provides a number of mapping instructions on
either the method or the class which map the Windows
names to Unix names (I've put it on the class here).

The standard Unix version is specified with the tag
"std-shared-object", and the standard Windows version
is specified with "std-win32-dll".  Overrides can be
specified by matching on the autoconf-chosen host
identifier. The CLR processes the instructions in order,
and uses the first it finds.

This doesn't solve the "different function name,
same purpose" problem, of course, but it does solve
a big part of the multi-platform import issues.

So as not to introduce too much embrace and extend,
I made the attribute "floating".  That is, it can be in
any namespace.  This allows a "private" class to be
put into the importing assembly called something like
"MyNamespace.DllImportMapAttribute".  This will
not pollute the global namespace, and so third party
programmers will not come to rely upon it by accident.

Cheers,

Rhys.