I want to implement a Mongoose (http://code.google.com/p/mongoose/) Binding in C#. There are some examples, but they don\'t work with the current version.
This is my cu
DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr mg_start(IntPtr callback, IntPtr userData,
[In][MarshalAsAttribute(UnmanagedType.LPArray,
ArraySubType=UnmanagedType.LPStr)] string[] options);
Haven't tried this, but I think this gets you there. You might need to make the ArraySubType be LPWStr if you want unicode in the C call. Making it LPStr gives you ANSI.
Are you doing the function pointers? That's where the real challenge is. Not so much from declaring and marshaling but rather from a pointer lifespan issue. If mg_start holds onto the unmanaged version of the delegate, you may find that the thunk gets garbage collected on you, in spite of what the documentation says. We've seen this happen so often that we've, where possible, rearchitected the underlying glue to not use that style of code.
Generally speaking, if the API is a chatty API with tons of callbacks, you're going to be hosed by the callbacks. You're better off trying to create a C++/CLI library that implements the API in a far less chatty way with clear managed/unmanaged boundaries.
I just wanted to suggest using C# binding, on the project page in the features they have:
Have you tried this?
In C# a char is an Unicode character, therefore consisting of two bytes. Using strings is not an option here, but you can use the Encoding.ASCII class to get the ASCII representation of the unicode string as a byte array:
byte[] asciiString = Encoding.ASCII.GetBytes(unicodeString);
C#'s arrays are references, aka pointers in C, so you can write your code as:
byte[][] options = {
Encoding.ASCII.GetBytes("document_root"),
Encoding.ASCII.GetBytes("/var/www"),
Encoding.ASCII.GetBytes("listening_ports"),
Encoding.ASCII.GetBytes("80,443s"),
null
};
You can't do anything about the const other than creating a wrapper class with read-only indexers and a private array of bytes, but this won't work in your case.
char[] in C# is a String.
Looks like you are defining a pointer to a char[]. In C this is the Array of Arrays, right? So in C# it would be just:
String[] options = {
"document_root", "/var/www",
"listening_ports", "80,443s",
NULL
};
Hope it helps.
Regards.
try
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr mg_start(int zero, IntPtr userData, string[] options);
and use IntPtr.Zero
as userdata
. and something like
new [] { "document_root", "/var/www", "listening_ports", "80,443s", null }
as options.