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?
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.
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.
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.
gcc -c -DBUILD_DLL sourcefile
dllwrap --output-lib=liboutputfile.a --dllname=name.dll --driver-name=gcc objectfile
Don't forget to wrap!
Quote from: rabbit on June 05, 2005, 04:29 PM
gcc -c -DBUILD_DLL sourcefile
dllwrap --output-lib=liboutputfile.a --dllname=name.dll --driver-name=gcc objectfile
Don't forget to wrap!
That yeilds even stranger results.
Quote from: NicoQwertyu on June 05, 2005, 03:34 PMQuotegcc 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 PMQuoteI 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.
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
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.
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.
HAH! I just realized. Use g++ for compiling c++ files.
Quote from: rabbit on June 05, 2005, 10:09 PM
HAH! I just realized. Use g++ for compiling c++ files.
I tried that before I posted this also. gcc is fully capable of compiling c++ files.
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");
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
Nevermind. I guess it doesn't make a difference. There must have been a different problem a while back when it wouldn't work.