How do decorated names get into import libraries when I only provide the undecorated name?

。_饼干妹妹 提交于 2019-12-23 00:49:11

问题


I'm working in Visual C++, VS2015 Community. I've written this tiny little DLL:

#include "stdafx.h"

int showMsgBox(wchar_t* caption, wchar_t* message)
{
    MessageBox(NULL, message, caption, 0);
    return 0;
}

And this tiny little client:

#include "stdafx.h"

__declspec(dllimport) int showMsgBox(wchar_t* caption, wchar_t* message);

int main()
{
    showMsgBox(L"SimpleDLLClient", L"Hello DLL World!");
    return 0;
}

To export the showMsgBox function, I've created this module definition file:

LIBRARY SimpleDLL

EXPORTS
    showMsgBox

When I link my client, I pass it the import library that was created when I linked my DLL. Everything compiles and links fine.

And that puzzles me.

According to MSDN, "Because the Visual C++ compiler uses name decoration for C++ functions, you must either use the decorated name as the entryname or internalname, or define the exported functions by using extern "C" in the source code."

But I'm not exporting a decorated name, am I?

If, instead of using a module definition file, I were to prefix the function with the __declspec(dllexport) extended attribute, I wouldn't be surprised (as this ought to have whatever name decoration the compiler applies match the same decoration applied by the compiler to the client).

Likewise, if I prefixed the function with 'extern "C"' in both the DLL and client code, that should also work (and it does: I tested it), because, again, the symbols should match.

But, I would have expected an undecorated export in the module definition file to fail to resolve the client's reference to the same undecorated name, when neither the DLL nor client code uses 'extern "C",' which seems also to be what MSDN says I should expect. Yet, exporting the undecorated name via the module definition file does work, even when I do not use 'extern "C"' anywhere.

Can anyone tell me why this works?

UPDATE

Looking into the files created by the linker, I see that putting the undecorated name into the module definition file apparently results in the decorated name being included in the import library. When I use dumpbin /exports on that file, here's what I get:

File Type: LIBRARY

     Exports

       ordinal    name

                  ?showMsgBox@@YAHPEA_W0@Z (int __cdecl showMsgBox(wchar_t  *,wchar_t *))

Now, somewhat amazingly (to me, anyway), if I explicitly alias the decorated name, like this:

LIBRARY SimpleDLL

EXPORTS
    showMsgBox=?showMsgBox@@YAHPEA_W0@Z

dumpbin tells me that this is what shows up in the import library:

File Type: LIBRARY

     Exports

       ordinal    name

                  showMsgBox

Using that as input to the linker when I build the client works fine too, provided that I use 'extern "C"' when I declare my imported function:

extern "C" int showMsgBox(wchar_t* caption, wchar_t* message);

That makes sense, since the symbol the linker is now looking for is the undecorated "showMsgBox," and I have aliased that symbol to the decorated name created when I compiled my DLL.

Soooo...

What it looks like to me is that pages and pages of MSDN documentation that all say you must use decorated names in module definitions files are mistaken. Rather, it appears that if you use the undecorated name in your module definition file, it is the decorated name that is actually incorporated into your import library, which will resolve the reference to the matching decorated name constructed when you compile your client code. That, of course, is what I would prefer, rather than having to extract the decorated names and use those in my module definition files. It just doesn't match what the MSDN pages repeatedly say.

I like to think I'm a bright boy, but it's pretty arrogant of anyone to suggest that Microsoft doesn't know how its own products work.

What am I missing here?

UPDATE 2

With the DLL and client both using decorated names (that is, no use of 'extern "C"' anywhere), everything builds fine with the undecorated name in the module defintion file, like I said. But, interestingly, with no changes at all to the source code, things build equally well if I do use the decorated name in the module definition file:

LIBRARY SimpleDLL

EXPORTS
    ?showMsgBox@@YAHPEA_W0@Z

At the binary level, the import library this creates is nearly identical to the library created when I use the undecorated name in the module definition file. The only differences appear to be time-stamps, with the exception of one byte near the end. Still trying to make sense of that one, but it appears ever more certain that, somehow, the linker is exporting the decorated name, even when the module definition file refers solely to the undecorated name.

来源:https://stackoverflow.com/questions/36295272/how-do-decorated-names-get-into-import-libraries-when-i-only-provide-the-undecor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!