Build a DLL

Well this is leading up to a new release of my SIMH projects. The issue that I’ve had with the SLiRP code (usermode NAT) is that it only works when built with GCC, and ONLY when you have no optimizations. Naturally you will loose all optimizations with SIMH if you build the entire project like that. And of course you cannot use Visual C++ to build SIMH, because while it’s faster they use different object files.

So while thinking about what a bummer it is, and how to try to debug SLiRP with Visual Studio, today I had a ‘better’ idea. Well ‘better’ in that I can do this way quicker.

Instead I’ll build SLiRP as a DLL, and have Visual C++ call that!

Ok, now that sounds crazy, but the first thing I’d need is a simple ‘test’ case. First let’s build a dll in MinGW. It took a bit of googling but then I found this super simple example.

dll.c

__declspec(dllexport) int hi(void)
{
return 3;
}

Ok, it doesn’t do that much, but you get the idea. Now we have to compile this with MinGW.

gcc -c dll.c
gcc -shared -o test.dll dll.o

Ok, now this will first compile the C file into an object file, then the linker will set it up as a DLL. Notice that I’m not building the ‘.a’ export file for this DLL. Visual C++ wouldn’t like it anyways, so I don’t need it.

Next, using Visual C++ (I would *assume* just about every version can do this..) I re-build the DLL to create the export library. Yes I know this is weird, but it is the quickest way I know to do this.

cl /c /LD dll.c
link /DLL dll.obj

Cool, now we’ve built dll.c as a DLL under both MinGW & Visual C++. Now for a ‘test’ program to drive our ‘staticly linked’ dynamic link library.

test.c

void main(void)
{
int j=hi();
printf(“%d\n”,j);
}

Ok, now with that out of the way, let’s compile & link!

cl test.c dll.lib

Cool, now we’ll have a test.exe!

Let’s run it!

c:\msys\1.0\src\dlltest>cl test.c dll.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80×86
Copyright (C) Microsoft Corporation. All rights reserved.

test.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

/out:test.exe
test.obj
dll.lib

c:\msys\1.0\src\dlltest>test
3

Wow that was exciting! Now for the people paying attention, you’ll remember that the test.exe was linked against dll.lib which was built with the Microsoft compiler, and is calling the Microsoft generated dll.dll. Yes you are correct. But always test with a known positive, before you throw in the negative I say…

c:\msys\1.0\src\dlltest>move test.dll dll.dll
Overwrite c:\msys\1.0\src\dlltest\dll.dll? (Yes/No/All): y
1 file(s) moved.

c:\msys\1.0\src\dlltest>test
3

Holy crap! It worked!!!!

That’s right, now I have built a very simple test program that’ll call a DLL function built with MinGW!

And that, is how you can get around a kooky problem where some programs build with one version of a compiler tweaked one way, and you want to use those bits in another program built another way.

Just ask any language refugee from the 1980’s how hard this was to do on the PC platform.. While VMS had a common library spec for all languages, not every platform (MS-DOS,UNIX) was as lucky. But with the rise of things like Windows with DLL’s, and of course NT thanks to the VMS crew it’s in modern systems today.

Let me tell you, linking Quick Basic to C was… not all that much fun. And Turbo C++ was right out!

Anyways I’ll leave you with this much, and at the worst case, much like making bootable CD’s, it’s a good note for me to find this stuff later when I need it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.