• Welcome to Valhalla Legends Archive.
 

DLL Function Name "Decoration"

Started by NicoQwertyu, June 05, 2005, 01:26 PM

Previous topic - Next topic

NicoQwertyu

I'm trying to build a DLL in gcc, but the function names always end up getting mangled.

I'm not sure if I'm doing something wrong, or if it's some wierd compiler issue (GCC and MinGW).


extern "C" __declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam);




__declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam) {

...

}



Compiled with:

gcc plugin_message.cpp -shared -o ../build/plugin_message.dll



The DLL compiles fine, but when I check the exports, the function name is still mangled.  Any one more experienced with this compiler know what the problem is?

OnlyMeat

You can specify specific export function names on the command line for the linker. However an easier way is to use a .def file in which the contents specify the exported names. For example:-

-- MyLib.def --

LIBRARY      "MyLib"
DESCRIPTION  "My exported library"

EXPORTS
   Function1 @1


Then add a /DEF: MyLib.def on the linker command line.

Generally name mangling shouldn't be a problem, unless you are calling from vb.

Kp

I usually don't mix C++ and DLLs, but I've never had the problem you're experiencing.  Did you actually put both those code blocks in one file?  Also, it's traditional to name C++ files with .cc not .cpp.  Among other advantages, it prevents MSVC++ from recognizing them.  If those two code blocks are in one file, I can raise a Windows box and check my build process for you.  I do some strange constructs to minimize the number of exported symbols and extra libraries drawn in, so I'd need to check my notes.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

NicoQwertyu

#3
OnlyMeat: I forgot to mention that I also tried using a .def file. 

Quotegcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def
Warning: resolving _msgproc by linking to _msgproc@12

While the DLL compiles, it renders some strange exports, and still doesn't export the function the way I want it to.



KP: Yeah, they're both in one file.

QuoteI usually don't mix C++ and DLLs

What for?  I'm still new to C++, so I'm open to any suggestions.  Even when I change the file extension to .c, and fix all the new errors generated by gcc, it still mangles the function name.


R.a.B.B.i.T

gcc -c -DBUILD_DLL sourcefile
dllwrap --output-lib=liboutputfile.a --dllname=name.dll --driver-name=gcc objectfile

Don't forget to wrap!


Kp

Quote from: NicoQwertyu on June 05, 2005, 03:34 PM
Quotegcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def
Warning: resolving _msgproc by linking to _msgproc@12

This is a serious warning!  In my opinion, it ought to be a full-blown error, actually.  It means you declared a function as _cdecl in one place, and as _stdcall in another, so calling it will corrupt your stack pointer.  This must be fixed before you can safely call msgproc.

Quote from: NicoQwertyu on June 05, 2005, 03:34 PM
QuoteI usually don't mix C++ and DLLs
What for?
The projects for which I want DLLs are generally low level and/or mix in some assembly, so C++ name mangling just gets to be a horrible nuisance.  There's no technical reason why you should or shouldn't prefer C over C++ for DLLs.

Quote from: NicoQwertyu on June 05, 2005, 03:34 PMI'm still new to C++, so I'm open to any suggestions.  Even when I change the file extension to .c, and fix all the new errors generated by gcc, it still mangles the function name.

That behavior definitely should not happen.  If gcc is compiling it as C code, it should not be mangling the name.  Just so I can be sure I try exactly your problem, run this in a command prompt and paste all the output back:

type plugin_message.cpp
gcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def


If you want to keep your message contents private, strip out the body of the function; all I really need are the lines at global scope.  Also, as one other thing to try: build to a .o file, then link the .o file and .def to make a DLL..  To do that:

gcc -c plugin_message.cpp
gcc plugin_message.o plugin_message.def -shared -o output.dll
This is from memory, but should work.  My build process is driven by interlocking makefiles and invokes ld directly, so that I can skip the cruft that the MinGW project normally drags in.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

NicoQwertyu

#7
First:

Quote
Kyle@NA-0060YM1FOOF2 ~/src/plugin_notepad/plugindll
$ type plugin_message.cpp
plugin_message.cpp is ./plugin_message.cpp

Kyle@NA-0060YM1FOOF2 ~/src/plugin_notepad/plugindll
$ gcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.
def
Warning: resolving _msgproc by linking to _msgproc@12
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

Kyle@NA-0060YM1FOOF2 ~/src/plugin_notepad/plugindll
$

Second:
Same output as first.


plugin_message.cpp -- function contents stripped out, not because I want to keep them private, but to save room.

Quote
#include <windows.h>
#include <string.h>


#define EXPORT __declspec(dllexport)
#define MSG_DOSTUFF 33001


void strippath(char *s);
void dostuff();
extern "C" __declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam);




bool in_target = false;


extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {

}



extern "C" __declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam) {

}


void dostuff() {

}


void strippath(char *s) {

}


plugin_message.def

Quote
LIBRARY "plugin_message.dll"
DESCRIPTION "mmmm"
EXPORTS
   msgproc @1


Makefile:

Quote
all: plugin_message.cpp
   gcc plugin_message.cpp plugin_message.def -shared -o ../build/plugin_message.dll


Kp

OK, I wasn't expecting a custom shell.  The msgproc warning is actually because you're trying to export it unnamed, which isn't nearly as bad as I initially thought.  You can make that go away by changing your .DEF file to read:
LIBRARY "plugin_message.dll"
DESCRIPTION "mmmm"
EXPORTS
   msgproc@12=msgproc @1
My Makefile comment was just explanation of why I didn't have the full link procedure on hand: because I do things in very complicated and bizarre ways. :)  I'll try out your code on my Windows box when I get to it and edit in my results.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

NicoQwertyu

Thanks for your replys, kp.  A quick comment before I go watch Starwars III.  Is that export correct?  When I switch it around (msgproc=msgproc@12 @1) is resolves the warning, and leaves the DLL with two exports (one of them being msgproc).  Ran into a new problem, however; GetProcAddress fails, but I'm sure that's my own fault.  I'll check back in a few hours.  Thanks again for your help.

R.a.B.B.i.T

HAH!  I just realized.  Use g++ for compiling c++ files.


NicoQwertyu

QuoteRan into a new problem, however; GetProcAddress fails, but I'm sure that's my own fault.

It was my fault :P!  Everything is working now. Thanks for all the replies.

FARPROC hfunc = GetProcAddress(hdll, "msgproc");

Apparently, is very different from:

FARPROC hfunc = GetProcAddress(hdll, (LPCSTR)"msgproc");

Kp

It shouldn't be.  I never cast strings that I pass to GetProcAddress.  Post a disassembly of both forms here, please. :)

objdump -d objfile.o
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!