Could someone familiar with command line compiling using GNU C/C++ Compiler Collection please help me with a Dll creation problem I have? What I would like to know is how to create a Windows Dll out of the following very simple test file that is essentially just a "Hello, World!" type thing...

//dllMain.cpp
#include <stdio.h>

void __stdcall Print(const char* pTxt)
{
 printf("%s\n", pTxt);
}

As you can see there is just one function which just outputs a char* to the console. The main wrinkles that have so far foiled all my attempts at this are that the function is defined as __stdcall not __cdecl, and I wish to use a Windows Module Definition File, i.e., a *.def file to indicate the exports to the linker - not __declspec(dllexport) or anything like that. Here is the def file. Lets call the project MkDll so that the module definition file is MkDll.def....

; MkDll.def
LIBRARY       "MkDll.dll"
DESCRIPTION   'SERVER Windows Dynamic Link Library'

EXPORTS
Print                PRIVATE

Here is what I have accomplished so far. My project directory is C:\Code\CodeBlks\MkDll...

C:\Code\CodeBlks\MkDll>g++ -c dllMain.cpp -o dllMain.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

02/28/2011  10:13 AM    <DIR>          .
02/28/2011  10:13 AM    <DIR>          ..
02/28/2011  10:10 AM                92 dllMain.cpp
02/28/2011  10:13 AM               391 dllMain.o
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:10 AM               148 MkDll.def
               4 File(s)            755 bytes
               2 Dir(s)  36,273,405,952 bytes free

C:\Code\CodeBlks\MkDll>

As can be seen above I have successfully compiled dllMain.cpp into dllMain.o From my research on the internet I have determined that my next critical step is to use DllTool.exe to read in my MkDll.def file and my dllMain.o object file and create an exports file and lib file. Below you can see my command line invocation of DllTool which I ran in verbose mode, followed by a dir listing...

C:\Code\CodeBlks\MkDll>DllTool -v -d MkDll.def -e expMkDll.o -l libMkDll.lib dllMain.o
DllTool: Processing def file: MkDll.def
DllTool: LIBRARY: MkDll.dll base: ffffffff
DllTool: Processed def file
DllTool: Scanning object file dllMain.o
DllTool: Done reading dllMain.o
DllTool: Processing definitions
DllTool: Processed definitions
DllTool: Generating export file: expMkDll.o
DllTool: Opened temporary file: dquc.s
DllTool: run: as   -o expMkDll.o dquc.s
DllTool: Generated exports file
DllTool: Creating library file: libMkDll.lib
DllTool: run: as   -o dquh.o dquh.s
DllTool: run: as   -o dqut.o dqut.s
DllTool: Created lib file

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

02/28/2011  10:25 AM    <DIR>          .
02/28/2011  10:25 AM    <DIR>          ..
02/28/2011  10:14 AM               605 CmdLnOutput.txt
02/28/2011  10:10 AM                92 dllMain.cpp
02/28/2011  10:13 AM               391 dllMain.o
02/28/2011  10:25 AM               716 expMkDll.o
02/28/2011  10:25 AM             1,510 libMkDll.lib
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
               7 File(s)          3,586 bytes
               2 Dir(s)  36,273,344,512 bytes free

C:\Code\CodeBlks\MkDll>

There do not appear to be any errors, and the dir listing seems to indicate my export lib and main library file have been created. The final step should be to run the linker and create my Dll, but that is where I'm getting stuck. I can't seem to find much in the way of documentation on running the ld linker directly, and most documentation shows calling the linker through gcc or g++. Here is my attempt...

g++ -shared -v dllMain.o expMkDll.o -o MkDll.dll

C:\Code\CodeBlks\MkDll>g++ -shared dllMain.o expMkDll.o -o MkDll.dll
expMkDll.o:fake:(.edata+0x38): undefined reference to `Print'
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>

As can be seen its failing, and I don't know what else to do. At this point, while I'd be thrilled if someone
could help me with just this, I'd like to briefly mention why I'm doing it, because as you might have guessed, its part of a larger problem. I'm trying to use the GNU C/C++ compiler Collection to create a working COM Dll. I'm not sure if anyone has ever even tried to do this. Creating a COM Dll with Microsoft's IDEs or command line compiling is of course very easy. All one needs to do to ensure that Dll export names will remain unmangled through the compile/linkage process is add the *.def file to the compilation string, or, in the case of just using the IDE, include it in the project files as part of the project and the Microsoft compilers will respect the contents of the def file.

I've unsuccessfully tried to use the Code::Blocks Ide, and now I'm trying command line compilation methods to accomplish this. Nothing I have tried works. My exports get continually mangled, and any system calls to the four critical COM exports DllRegisterServer(), DllUnregisterServer(), DllGetClassObject(), and DllCanUnloadNow() fail. COM's Service Control Manager ( SCM ) can successfully do a LoadLibrary() on the COM Dll, but can't locate the functions with GetProcAddress() due to GNU not respecting the export names in my def file. No one at the Code::Blocks Forums have helped me, and the MinGw site has been down for days.

So can anyone help with my simple Dll above? If you can, I'm pretty sure I can manage the rest.

It seems you are doing the steps correctly (I'm not sure since I rarely use DLLs and Windows). To avoid the name-mangling problem. You need to make all your functions "extern "C"". This tells the compiler to use C name-mangling (which is basically no mangling at all). Every compiler has a different pattern for name-mangling in C++ (it is not that GCC is not "respecting" export names).

The dlltool call will try to "publish" export names that it contains and link those names to functions in your .o file. But I would assume that it will not be looking for GCC mangled names. So, either use extern "C" to disable the mangling, or try to find an option in dlltool that creates the exports in a way that it looks for GCC mangled names.

Thanks for the input Mike! I'm getting closer! The extern “C” thing always confuses me. I find myself not always sure when/if to use it. Anyway, I added it to my Dll function, and that finally allowed for a successful compile/link…

#include <stdio.h>

extern "C" void __stdcall Print(const char* pTxt)
{
 printf("%s\n", pTxt);
}

I did get these warnings, however…

Warning: resolving _Print by linking to _Print@4
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

But when I used Microsoft’s DumpBin.exe utility on the Dll, it looked like it exported the symbol ‘Print’ exactly the way I wanted it…

C:\Code\CodeBlks\MkDll>dumpbin /exports MkDll.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file MkDll.dll

File Type: DLL

  Section contains the following exports for expMkDll.o.dll

           0 characteristics
    4D6BF1F7 time date stamp Mon Feb 28 14:05:27 2011
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000011D8 Print

  Summary

        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        1000 .debug_info
        1000 .debug_line
        1000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_ranges
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text

In the above dump note the text Print. That is just how it should be. With high hopes next I decided to throw together a quick host to see if it works, so I made this…

//Host.cpp
//g++ Host.cpp libMkDll.lib -o Host.exe
#include <stdio.h>
void __stdcall Print(const char*);

int main()
{
 char szBuffer[]="Hello, World!";
 Print(szBuffer);
 getchar();
 
 return 0; 
}

But upon trying to compile it I got this…

C:\Code\CodeBlks\MkDll>g++ Host.cpp libMkDll.lib -o Host.exe
C:\DOCUME~1\Fred\LOCALS~1\Temp\ccCLeItq.o:Host.cpp:(.text+0x25): undefined reference to `Print(char const*)@4'
collect2: ld returned 1 exit status

I probably don’t have to tell you how stubborn computers can be when they don’t want to do something! I tried it too with the extern “C” prefacing the Print declaration in the host, and also fooled around with the const keyword to no avail. Bummer!

Aren't you supposed to write:

$ g++ Host.cpp -l libMkDll.lib -o Host.exe

You're right! I think I missed that. I have no explanation for the problem I'm getting now though. I think I deserve an A for effort though....

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l libMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp -llibMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l C:\Code\CodeBlks\MkDll\libMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -lC:\Code\CodeBlks\MkDll\libMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l libMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp L"C:\Code\CodeBlks\MkDll" -l libMkDll.lib -o Host.exe
g++: LC:\Code\CodeBlks\MkDll: Invalid argument

C:\Code\CodeBlks\MkDll>g++ Host.cpp -LC:\Code\CodeBlks\MkDll -l libMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

02/28/2011  03:56 PM    <DIR>          .
02/28/2011  03:56 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  02:36 PM               109 dllMain.cpp
02/28/2011  02:36 PM               376 dllMain.o
02/28/2011  02:37 PM               716 expMkDll.o
02/28/2011  02:43 PM               205 Host.cpp
02/28/2011  02:37 PM             1,510 libMkDll.lib
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
02/28/2011  02:38 PM            22,421 MkDll.dll
               9 File(s)         31,368 bytes
               2 Dir(s)  36,253,954,048 bytes free

C:\Code\CodeBlks\MkDll>g++ Host.cpp -L./ -llibMkDll.lib -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.lib
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l libMkDll.a -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.a
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.cpp -L C:\Code\CodeBlks\MkDll -l libMkDll.a -o Host.exe
c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/ld.exe: cannot find -llibMkDll.a
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>dumpbin libMkDll.a
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file libMkDll.a

File Type: LIBRARY

  Summary

           0 .bss
           0 .data
          14 .idata$2
           8 .idata$4
           8 .idata$5
          10 .idata$7
           0 .text

C:\Code\CodeBlks\MkDll>dumpbin MkDll.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file MkDll.dll

File Type: DLL

  Summary

        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        1000 .debug_info
        1000 .debug_line
        1000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_ranges
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text

C:\Code\CodeBlks\MkDll>dumpbin /exports MkDll.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file MkDll.dll

File Type: DLL

  Section contains the following exports for expMkDll.o.dll

           0 characteristics
    4D6BF973 time date stamp Mon Feb 28 14:37:23 2011
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000011D8 Print

  Summary

        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        1000 .debug_info
        1000 .debug_line
        1000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_ranges
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text

C:\Code\CodeBlks\MkDll>

About mid way through I put libMkDll.lib right in the \lib directory of my MinGw installation. Still no dice (I'll start doing stuff like that when I get desperate)! Then I got the idea maybe it didn't like my .lib extension cuz Linux/Unix uses .a, so I changed it to that. Its starting to wear me down!

Don't change the extension to .a (.lib and .a are not exactly the same thing, but equivalent). It appears that proper way to do it is to omit the extension in the command-line (but leave it in the filename), as such:

$ g++ Host.cpp -l libMkDll -o Host.exe

Given "-lfoo", the ld.exe of MinGW will first look for "libfoo.a" if it is not found, it will look for "foo.lib". In other words, with "-llibMkDll", it should find the file "libMkDll.lib" (note that normally, you don't name .lib files with the "lib" prefix).

Hello Mike!

You’ve really been a trooper trying to help with this! Thanks!

Still doesn't work though. When my host is like so…

//without extern "C"

//g++ Host.cpp -l libMkDll -o Host.exe
#include <stdio.h>
void __stdcall Print(const char*);

int main()
{
 const char* const pStr = "Hello, World!";
 Print(pStr);
 getchar();
 
 return 0; 
}

I get this…

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l libMkDll -o Host.exe
C:\DOCUME~1\Fred\LOCALS~1\Temp\ccrTHitH.o:Host.cpp:(.text+0x25): undefined reference to `Print(char const*)@4'
collect2: ld returned 1 exit status

…and when like so….

//with extern "C"

//g++ Host.cpp –l libMkDll -o Host.exe
#include <stdio.h>
extern “C” void __stdcall Print(const char*);

int main()
{
 const char* const pStr = "Hello, World!";
 Print(pStr);
 getchar();
 
 return 0; 
}

…I get instead this…

C:\Code\CodeBlks\MkDll>g++ Host.cpp -l libMkDll -o Host.exe
C:\DOCUME~1\Fred\LOCALS~1\Temp\ccK4JLHV.o:Host.cpp:(.text+0x25): undefined reference to `Print@4'
collect2: ld returned 1 exit status

Can’t win no-how! I’m beginning to dispair that this indeed can’t be done with GNU.

Because I was having such difficulties with this, I decided to see if I could satisfactorily create a working Dll that was simpler in that I wouldn’t be using a *.def file or the __stdcall stack setup. I was able to do that finally, and here is that code…

Step 1: Compile Dll Code To Object File ( *.o );

//dllMain.cpp
#include <stdio.h>

extern "C" void Print(char* pTxt)
{
 printf("%s\n", pTxt);
}
C:\Code\CodeBlks\MkDll>g++ -c dllMain.cpp -o dllMain.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  11:48 AM    <DIR>          .
03/01/2011  11:48 AM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  08:43 PM                87 dllMain.cpp
03/01/2011  11:48 AM               372 dllMain.o
03/01/2011  11:45 AM               196 Host.cpp
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
02/28/2011  08:42 PM    <DIR>          sav1
               6 File(s)          6,686 bytes
               3 Dir(s)  36,252,704,768 bytes free

Step 2: Use DllTool.exe To Create Exports File And Lib file;

C:\Code\CodeBlks\MkDll>DllTool -e expMkDll.o -l MkDll.lib dllMain.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  11:50 AM    <DIR>          .
03/01/2011  11:50 AM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  08:43 PM                87 dllMain.cpp
03/01/2011  11:48 AM               372 dllMain.o
03/01/2011  11:50 AM               288 expMkDll.o
03/01/2011  11:45 AM               196 Host.cpp
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  11:50 AM             1,494 MkDll.lib
02/28/2011  08:42 PM    <DIR>          sav1
               8 File(s)          8,468 bytes
               3 Dir(s)  36,252,700,672 bytes free

Step 3: Use g++ To Compile Dll From Exports File And Dll Object File (dllMain.o);

C:\Code\CodeBlks\MkDll>g++ -shared dllMain.o expMkDll.o -o MkDll.dll

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  11:54 AM    <DIR>          .
03/01/2011  11:54 AM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  08:43 PM                87 dllMain.cpp
03/01/2011  11:48 AM               372 dllMain.o
03/01/2011  11:50 AM               288 expMkDll.o
03/01/2011  11:45 AM               196 Host.cpp
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  11:54 AM            22,241 MkDll.dll
03/01/2011  11:50 AM             1,494 MkDll.lib
02/28/2011  08:42 PM    <DIR>          sav1
               9 File(s)         30,709 bytes
               3 Dir(s)  36,252,659,712 bytes free

Step 4: Dump Exports To See How Print Was Exported From Dll;

C:\Code\CodeBlks\MkDll>dumpbin /exports MkDll.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file MkDll.dll

File Type: DLL

  Section contains the following exports for MkDll.dll

           0 characteristics
    4D6D24DA time date stamp Tue Mar 01 11:54:50 2011
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000011D8 Print

  Summary

        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        1000 .debug_info
        1000 .debug_line
        1000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_ranges
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text

Step 5: Compile Host.cpp Into Object Code ( Host.o );

//g++ -c Host.cpp -o Host.o
#include <stdio.h>
extern "C" void Print(char*);

int main()
{
 char szBuffer[] = "Hello, World!";
 Print(szBuffer);
 getchar();

 
 return 0; 
}
C:\Code\CodeBlks\MkDll>g++ -c Host.cpp -o Host.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  11:56 AM    <DIR>          .
03/01/2011  11:56 AM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  08:43 PM                87 dllMain.cpp
03/01/2011  11:48 AM               372 dllMain.o
03/01/2011  11:50 AM               288 expMkDll.o
03/01/2011  11:45 AM               196 Host.cpp
03/01/2011  11:56 AM               884 Host.o
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  11:54 AM            22,241 MkDll.dll
03/01/2011  11:50 AM             1,494 MkDll.lib
02/28/2011  08:42 PM    <DIR>          sav1
              10 File(s)         31,593 bytes
               3 Dir(s)  36,252,659,712 bytes free

Step 6: Compile Host.o Into Host.exe Linking To Dll Using Export Lib And Dll:

C:\Code\CodeBlks\MkDll>g++ Host.o MkDll.lib MkDll.dll -o Host.exe

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  12:02 PM    <DIR>          .
03/01/2011  12:02 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
02/28/2011  08:43 PM                87 dllMain.cpp
03/01/2011  11:48 AM               372 dllMain.o
03/01/2011  11:50 AM               288 expMkDll.o
03/01/2011  11:45 AM               196 Host.cpp
03/01/2011  12:02 PM            25,530 Host.exe
03/01/2011  11:56 AM               884 Host.o
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  11:54 AM            22,241 MkDll.dll
03/01/2011  11:50 AM             1,494 MkDll.lib
02/28/2011  08:42 PM    <DIR>          sav1
              11 File(s)         57,123 bytes
               3 Dir(s)  36,252,631,040 bytes free

C:\Code\CodeBlks\MkDll>Host.exe
Hello, World!


SUCCESS!!!!!!!!!!!!!

However, I had no luck repeating the above success with the __stdcall and def file additions. Here is the best I could do…

Step 1: Compile dllMain.cpp To Object File ( dllMain.o );

//dllMain.cpp
//g++ -c dllMain.cpp -o dllMain.o
#include <stdio.h>

extern "C" void __stdcall Print(char* pTxt)
{
 printf("%s\n", pTxt);
}
C:\Code\CodeBlks\MkDll>g++ -c dllMain.cpp -o dllMain.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  12:23 PM    <DIR>          .
03/01/2011  12:23 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
03/01/2011  12:23 PM               112 dllMain.cpp
03/01/2011  12:23 PM               376 dllMain.o
02/28/2011  08:29 PM               216 Host.cpp
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
02/28/2011  08:42 PM    <DIR>          sav1
03/01/2011  12:20 PM    <DIR>          sav2
               6 File(s)          6,735 bytes
               4 Dir(s)  36,252,532,736 bytes free

Step 2: Use DllTool To Read In MkDll.def File (Module Definition File), Create Export lib and Library File ( *.lib );

C:\Code\CodeBlks\MkDll>DllTool -v -d MkDll.def -e expMkDll.o -l libMkDll.lib dllMain.o
DllTool: Processing def file: MkDll.def
DllTool: LIBRARY: MkDll.dll base: ffffffff
DllTool: Processed def file
DllTool: Scanning object file dllMain.o
DllTool: Done reading dllMain.o
DllTool: Processing definitions
DllTool: Processed definitions
DllTool: Generating export file: expMkDll.o
DllTool: Opened temporary file: dclec.s
DllTool: run: as   -o expMkDll.o dclec.s
DllTool: Generated exports file
DllTool: Creating library file: libMkDll.lib
DllTool: run: as   -o dcleh.o dcleh.s
DllTool: run: as   -o dclet.o dclet.s
DllTool: Created lib file

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  12:25 PM    <DIR>          .
03/01/2011  12:25 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
03/01/2011  12:23 PM               112 dllMain.cpp
03/01/2011  12:23 PM               376 dllMain.o
03/01/2011  12:25 PM               716 expMkDll.o
02/28/2011  08:29 PM               216 Host.cpp
03/01/2011  12:25 PM             1,510 libMkDll.lib
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
02/28/2011  08:42 PM    <DIR>          sav1
03/01/2011  12:20 PM    <DIR>          sav2
               8 File(s)          8,961 bytes
               4 Dir(s)  36,252,528,640 bytes free

Step 3: Try To Create Actual Dll;

C:\Code\CodeBlks\MkDll>g++ -shared -v dllMain.o expMkDll.o -o MkDll.dll
Using built-in specs.
Target: mingw32
Configured with: ../../gcc-4.4.1/configure --prefix=/mingw --build=mingw32 --enable-languages=c,ada,c++,fortran,objc,obj-c++ --disable-nls --disable-win32-registry --enable-libg
omp --enable-cxx-flags='-fno-function-sections -fno-data-sections' --disable-werror --enable-threads --disable-symvers --enable-version-specific-runtime-libs --enable-fully-dyna
mic-string --with-pkgversion='TDM-2 mingw32' --enable-sjlj-exceptions --with-bugurl=http://www.tdragon.net/recentgcc/bugs.php
Thread model: win32
gcc version 4.4.1 (TDM-2 mingw32)
COMPILER_PATH=c:/program files/codeblocks/mingw/bin/../libexec/gcc/mingw32/4.4.1/;c:/program files/codeblocks/mingw/bin/../libexec/gcc/;c:/program files/codeblocks/mingw/bin/../
lib/gcc/mingw32/4.4.1/../../../../mingw32/bin/
LIBRARY_PATH=c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/;c:/program files/codeblocks/mingw/bin/../lib/gcc/;c:/program files/codeblocks/mingw/bin/../lib/gcc/m
ingw32/4.4.1/../../../../mingw32/lib/;c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../
COLLECT_GCC_OPTIONS='-shared' '-v' '-o' 'MkDll.dll' '-mtune=i386'
 c:/program files/codeblocks/mingw/bin/../libexec/gcc/mingw32/4.4.1/collect2.exe --shared -Bdynamic -e _DllMainCRTStartup@12 --enable-auto-image-base -o MkDll.dll c:/program fil
es/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../dllcrt2.o c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/crtbegin.o -Lc:/program files/codeblocks/mingw
/bin/../lib/gcc/mingw32/4.4.1 -Lc:/program files/codeblocks/mingw/bin/../lib/gcc -Lc:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../../mingw32/lib -Lc:/pr
ogram files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/../../.. dllMain.o expMkDll.o -lstdc++ -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -ls
hell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/crtend.o
Warning: resolving _Print by linking to _Print@4
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  12:28 PM    <DIR>          .
03/01/2011  12:28 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
03/01/2011  12:23 PM               112 dllMain.cpp
03/01/2011  12:23 PM               376 dllMain.o
03/01/2011  12:25 PM               716 expMkDll.o
02/28/2011  08:29 PM               216 Host.cpp
03/01/2011  12:25 PM             1,510 libMkDll.lib
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  12:28 PM            22,421 MkDll.dll
02/28/2011  08:42 PM    <DIR>          sav1
03/01/2011  12:26 PM    <DIR>          sav2
               9 File(s)         31,382 bytes
               4 Dir(s)  36,252,499,968 bytes free

C:\Code\CodeBlks\MkDll>dumpbin /exports MkDll.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file MkDll.dll

File Type: DLL

  Section contains the following exports for expMkDll.o.dll

           0 characteristics
    4D6D2BFB time date stamp Tue Mar 01 12:25:15 2011
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000011D8 Print

  Summary

        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        1000 .debug_info
        1000 .debug_line
        1000 .debug_loc
        1000 .debug_pubnames
        1000 .debug_ranges
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text

Step 4: Compile Host.cpp;

//g++ -c Host.cpp -o Host.o
#include <stdio.h>
extern "C" void __stdcall Print(char*);

int main()
{
 char szBuffer[] = "Hello, World!";
 Print(szBuffer);
 getchar();

 
 return 0; 
}
C:\Code\CodeBlks\MkDll>g++ -c Host.cpp -o Host.o

C:\Code\CodeBlks\MkDll>dir
 Volume in drive C is Main
 Volume Serial Number is 0C18-9CF6

 Directory of C:\Code\CodeBlks\MkDll

03/01/2011  12:32 PM    <DIR>          .
03/01/2011  12:32 PM    <DIR>          ..
02/28/2011  11:32 AM             5,759 CmdLnOutput.txt
03/01/2011  12:23 PM               112 dllMain.cpp
03/01/2011  12:23 PM               376 dllMain.o
03/01/2011  12:25 PM               716 expMkDll.o
03/01/2011  12:31 PM               207 Host.cpp
03/01/2011  12:32 PM               900 Host.o
03/01/2011  12:25 PM             1,510 libMkDll.lib
02/28/2011  10:07 AM               124 MkDll.bat
02/28/2011  10:19 AM               148 MkDll.def
03/01/2011  12:28 PM            22,421 MkDll.dll
02/28/2011  08:42 PM    <DIR>          sav1
03/01/2011  12:26 PM    <DIR>          sav2
              10 File(s)         32,273 bytes
               4 Dir(s)  36,252,495,872 bytes free

Step 5: Try To Create Host.exe Using Host.o, libMkDll.lib, and MkDll.dll...


C:\Code\CodeBlks\MkDll>g++ Host.o libMkDll.lib MkDll.dll -o Host.exe
Host.o:Host.cpp:(.text+0x35): undefined reference to `Print@4'
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ -c Host.cpp -o Host.o

C:\Code\CodeBlks\MkDll>g++ Host.o libMkDll.lib MkDll.dll -o Host.exe
Host.o:Host.cpp:(.text+0x35): undefined reference to `Print(char*)@4'
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>g++ Host.o -l libMkDll MkDll -o Host.exe
g++: MkDll: No such file or directory

C:\Code\CodeBlks\MkDll>g++ Host.o -l libMkDll MkDll.dll -o Host.exe
Host.o:Host.cpp:(.text+0x35): undefined reference to `Print(char*)@4'
collect2: ld returned 1 exit status

C:\Code\CodeBlks\MkDll>


FAILURE! CAN'T LINK!

At this point I think its time for me to give up Mike. I’ve lost a lot of time on this. Several years ago I lost about a day on it. I was developing a COM tutorial and wanted to show how to create the object with both the Microsoft and GNU compilers. I failed then and put it aside as ‘unfinished business’.

This time I sank several days into it and have come up empty. If it can be done I’m quite sure I can’t figure it out. Thanks a lot for you help on this though. I mean it!

Fred

One last point though... DllTool has a number of flags such as the -k flag that mention about eliminating the @# symbols from the exports. I tried it but to no apparent effect. I also tried implementing that stuff about fixup errors, but that didn't work either - at least for me.

This article has been dead for over six months. Start a new discussion instead.