Author | Message | Time |
---|---|---|
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). [code] extern "C" __declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam); [/code] [code] __declspec(dllexport) LRESULT CALLBACK msgproc(int nCode, WPARAM wParam, LPARAM lParam) { ... } [/code] Compiled with: [code] gcc plugin_message.cpp -shared -o ../build/plugin_message.dll [/code] 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? | June 5, 2005, 6:26 PM |
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 -- [code] LIBRARY "MyLib" DESCRIPTION "My exported library" EXPORTS Function1 @1 [/code] 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. | June 5, 2005, 8:18 PM |
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. | June 5, 2005, 8:21 PM |
NicoQwertyu | OnlyMeat: I forgot to mention that I also tried using a .def file. [quote]gcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def Warning: resolving _msgproc by linking to _msgproc@12[/quote] 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. [quote]I usually don't mix C++ and DLLs[/quote] 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. | June 5, 2005, 8:34 PM |
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! | June 5, 2005, 9:29 PM |
NicoQwertyu | [quote author=rabbit link=topic=11773.msg114970#msg114970 date=1118006944] gcc -c -DBUILD_DLL sourcefile dllwrap --output-lib=liboutputfile.a --dllname=name.dll --driver-name=gcc objectfile Don't forget to wrap! [/quote] That yeilds even stranger results. | June 5, 2005, 10:03 PM |
Kp | [quote author=NicoQwertyu link=topic=11773.msg114966#msg114966 date=1118003696][quote]gcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def Warning: resolving _msgproc by linking to _msgproc@12[/quote][/quote] 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 author=NicoQwertyu link=topic=11773.msg114966#msg114966 date=1118003696][quote]I usually don't mix C++ and DLLs[/quote]What for?[/quote] 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 author=NicoQwertyu link=topic=11773.msg114966#msg114966 date=1118003696]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.[/quote] 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: [pre]type plugin_message.cpp gcc plugin_message.cpp -shared -o ../build/plugin_message.dll plugin_message.def[/pre] 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: [pre]gcc -c plugin_message.cpp gcc plugin_message.o plugin_message.def -shared -o output.dll[/pre]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. | June 5, 2005, 10:43 PM |
NicoQwertyu | 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 $ [/quote] 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) { } [/quote] plugin_message.def [quote] LIBRARY "plugin_message.dll" DESCRIPTION "mmmm" EXPORTS msgproc @1 [/quote] Makefile: [quote] all: plugin_message.cpp gcc plugin_message.cpp plugin_message.def -shared -o ../build/plugin_message.dll [/quote] | June 5, 2005, 11:05 PM |
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:[pre]LIBRARY "plugin_message.dll" DESCRIPTION "mmmm" EXPORTS msgproc@12=msgproc @1[/pre]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. | June 6, 2005, 12:38 AM |
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. | June 6, 2005, 1:35 AM |
R.a.B.B.i.T | HAH! I just realized. Use g++ for compiling c++ files. | June 6, 2005, 3:09 AM |
NicoQwertyu | [quote author=rabbit link=topic=11773.msg115013#msg115013 date=1118027346] HAH! I just realized. Use g++ for compiling c++ files. [/quote] I tried that before I posted this also. gcc is fully capable of compiling c++ files. | June 6, 2005, 3:41 AM |
NicoQwertyu | [quote]Ran into a new problem, however; GetProcAddress fails, but I'm sure that's my own fault.[/quote] It was my fault :P! Everything is working now. Thanks for all the replies. [size=1]FARPROC hfunc = GetProcAddress(hdll, "msgproc");[/size] Apparently, is very different from: [size=1]FARPROC hfunc = GetProcAddress(hdll, (LPCSTR)"msgproc");[/size] | June 6, 2005, 6:11 AM |
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 | June 6, 2005, 11:31 PM |
NicoQwertyu | Nevermind. I guess it doesn't make a difference. There must have been a different problem a while back when it wouldn't work. | June 7, 2005, 12:54 AM |