MC++ is nice. It lets you mix unmanaged and managed code and allows you to easily create assemblies where you need to do a lot of interop work. Unfortunately, MC++ is not available for .NET CF. So, whenever you need to do any significant degree of interop, you usually end up doing one of the following:
- Doing a lot of PInvokes into code that really isn't PInvoke friendly. This generally results in a lot of manual marshalling of arguments and unsafe code. This doesn't work if what you need to PInvoke is a .lib or a non-flat/C style DLL.
- Writing a unmanaged DLL that does all the heavy lifting, and creating managed PInvokes to access it.
- Writing a COM object for Windows Mobile and referencing that in your C# project.
The first solution is pretty kludgy, but it works. The latter two solutions result in two outputs: a managed assembly and an interop DLL. The DLLs must always be deployed with each other to function properly. Not a very elegant solution either.
I've been playing with SQLite recently. SQLite is the most used database engine in the world, and it runs on basically any device imaginable, including Windows Mobile. SQLite is written entirely in C/C++, so naturally someone wrote a managed wrapper for it called System.Data.SQLite.
One of the interesting things I noticed about System.Data.SQLite is that it somehow manages to deploy as one assembly, even though one of the source DLLs is managed and the other is an unmanaged interop. After diving into the managed code, I noticed something quite peculiar: it was calling PInvokes contained within itself! Somehow a single DLL contained both managed and unmanaged code!
Turns out that the creator of SQLite also created a tool called Mergebin that allows you to merge your managed assembly and unmanaged interop assembly into one nice bow tied package. Very elegant! The full source to the Mergebin tool is included with System.Data.SQLite. I looked over it, and although I have a very rough idea of how DLLs work, so the actual technical implementation of it is all Greek to me. Interesting stuff nonetheless!
Just a few posts ago, I talked about how I managed to combine two .NET assemblies into one. It involved embedding one assembly as a resource of it's dependent assembly. Pretty kludgy. I probably should have Googled to see if there was a tool possible to merge two .NET assemblies, and there is: ILMerge. I haven't looked into it at all though, so I'm not sure if it will work for .NET CF.