November 19, 2006 6 Comments
First of all — This was a fairly intractable problem. I had to spend almost a full day to resolve it. There are many steps here and let’s go through them one by one:
Compiling a Win32 DLL using Cygwin/MingW
This was the hardest part. First of all, you should read Building and Using DLLs in the Cygwin manual. For me the linker flag "–export-all-symbols" didn’t work and I had to include a DEF file (read about it here).
Now, if it works you are darned lucky and I am jealous. In my case, on trying to link to my C# project, this gave an error about versioning with the cygwin1.dll. To be able to call from a .NET executable, you would want to compile it without dependancy on cygwin1.dll. Time to read another tutorial — Building MingW executables using Cygwin.
Runs without GCC throwing any tantrums? Lucky boy! Go to step 2. If it doesn’t (specifically saying undefined references for ___assert and ___getreent etc.), make sure that you are adding the "-mno-cygwin" flag to all the files that you compile, even when you are compiling from code to object files or else it will include the wrong headers. Perhaps the best option is to replace "gcc" by "gcc -mno-cygwin" everywhere.
If get compiler errors even now, you will just have to hack around in the code until you can fix it. Tough luck, baby, but that’s the way it is.
Before you move to the next step, just spend a time to check if the correct symbols have been exported. Run "dumpbin /exports <dll-name>" and you should be able to find all the symbols that the DLL exports. You can find more details about dumpbin here.
Calling a native assembly in C#
This is the easier part. You can called unmanaged DLLs from within .NET managed code by using P/Invoke through the DllImport attribute. It is as straight forward as:
public extern static void foo(System.Uint32 num, System.IntPtr ptr);
and calling foo. But, it wouln’t hurt to read a little more about it right? So there you go:
A word of caution: Do not try and reference the Win32 Assembly from within your VStudio IDE. It just crashed for me. Just copy the DLL file you create above into the Debug\bin\ or Release\Bin directory of your project.
So, there you go! One day’s hard work saved for you.