what about the other way aorund? Can VC++ actually generate a .DEF file at build time?
It never is other way round with VC. DEF file always is an input information, and VC never generates it. It's always programmer who does. Though I can recall, Borland indeed had the tool, but not VC.
Originally Posted by John E
If I see this in a DEF file:-
Code:
foo1 @2
will the LIB / DLL tables contain BOTH the function name and the ordinal or just the ordinal? I'm assuming both
It will be both, yes.
Originally Posted by egawtry
The NONAME is for the paranoid, I assume that Igor did it out of habit.
Sorry, the NONAME is for those who know exactly what they do. I used it precisely for demonstrating how conflict of ordinals may occur. Other people may use it for getting rid of export names table, because they have their own reasons for that, and being paranoid might be the last one. You know, sometimes people intentionally design all the aspects of the dlls they release.
Originally Posted by egawtry
The most commonly used extension is to put PRIVATE in place of the ordinal number for predefined Windows exports like DllGetVersion().
Well, talking about PRIVATE, again it is for those who know exactly what they do. It's used strictly to prevent existing export entries from appearing in import library. And frankly, I cannot see how PRIVATE could relate to the subject we discuss here, as it affects neither export name nor ordinal.
Originally Posted by John E
As long as the lib and its header files match each other, the exe build will always work just fine. The linker can't know if there's a more recent DLL available.
And if the prototype stays unchanged, and .lib file contains export by name, and export really exists in the .dll, it doesn't matter how old the .lib is, as .exe is going to work just fine.
Last edited by Igor Vartanov; January 4th, 2012 at 06:30 PM.
Sorry, the NONAME is for those who know exactly what they do. I used it precisely for demonstrating how conflict of ordinals may occur. Other people may use it for getting rid of export names table, because they have their own reasons for that, and being paranoid might be the last one. You know, sometimes people intentionally design all the aspects of the dlls they release.
The only reason I have ever seen, in spite of the "size" issue, is for people who are paranoid about security. It removes all possibility of easily hacking the DLL without having to disassemble it. These are the same people who strip then bootstrap their EXE files with encryption.
For someone learning, and for most of the rest of us, a simple export without any extra gunk is just fine. I have had no cause to use any extension besides PRIVATE in twenty years of Windows programming.
The only reason I have ever seen, in spite of the "size" issue, is for people who are paranoid about security. It removes all possibility of easily hacking the DLL without having to disassemble it.
Well, to deduce the function name behind the ordinal it's enough to inspect the .lib file. So it's somewhat weak approach to secure your dll by stripping export names. Of course, if the intention really was that.
Code:
D:\Temp\24>dumpbin /exports 24dll_noname.2.lib
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file 24dll_noname.2.lib
File Type: LIBRARY
Exports
ordinal name
3 _foo1
_foo2
Summary
D2 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
12 .idata$6
D:\Temp\24>dumpbin /exports 24dll_noname.2.dll
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file 24dll_noname.2.dll
File Type: DLL
Section contains the following exports for 24dll_noname.dll
00000000 characteristics
4F04C94C time date stamp Thu Jan 05 01:49:00 2012
0.00 version
3 ordinal base
2 number of functions
1 number of names
ordinal hint RVA name
4 0 00001030 foo2
3 00001000 [NONAME]
Summary
4000 .data
5000 .rdata
2000 .reloc
11000 .text
For someone learning, and for most of the rest of us, a simple export without any extra gunk is just fine. I have had no cause to use any extension besides PRIVATE in twenty years of Windows programming.
If you were right, John never would have any problem with ordinals. And we would lose such an opportunity to talk about dll quirks and perks.
So you are talking about some common case. While I'm still trying to stay in context of the original issue, when problem happened to developer, not end user.
I opened my exe in the Dependency Walker. It links to around 30 "primary" DLLs (some of which link to other DLLs of course). Except for the main system DLLs (kernel32.dll etc) all the primary DLLs were built with reference to a .DEF file but in the EXPORTS section, they typically show only function names, like so:-
Code:
g_array_new
g_array_ref
g_array_unref
etc, etc. Note, no ordinal numbers specified. Does this mean that the function will get imported by name?
The reason I'm asking is that in every case where I've built the DLL myself (using MSVC) Dependency Walker shows that my app is importing the DLL functions by name (even though the DLL was referenced to a DEF file just like the above example). But with the (thankfully small) number of 3rd party MinGW DLLs, every imported function is being imported by ordinal value.
For an MSVC-built app to import using ordinal values, they seem to have to be explicitly specified in the DEF file when building the DLL. This contradicts several things I've read elsewhere today - which suggested that a DEF file effectively suppresses exporting by name and instead, forces exporting by ordinal value. If no ordinal value was stipulated in the DEF file, default ones get substituted according to what I've read. That seems to be slightly wrong. From what I've observed, specifying only a name will place both a name and a (default) number into the DLL but forces the eventual app to import by name. Specifying both a name and number does broadly the same but forces the app to import by the specified number. Finally, specifying NONAME exports only a number. Am I on the right lines with all that?
Last edited by John E; January 4th, 2012 at 08:13 PM.
"A problem well stated is a problem half solved.” - Charles F. Kettering
This contradicts several things I've read elsewhere today - which suggested that a DEF file effectively suppresses exporting by name and instead, forces exporting by ordinal value.
DEF file just instructs how export tables need to be formed. If ordinals provided, it really forces the name to be bound to the explicit ordinal. And only NONAME instructs to prevent the name from appearing in export names. Where can you see a contradiction? Please note, here we talk only about dll exports, not about how the import entries get resolved on exe launch.
If no ordinal value was stipulated in the DEF file, default ones get substituted according to what I've read. That seems to be slightly wrong. From what I've observed, specifying only a name will place both a name and a (default) number into the DLL but forces the eventual app to import by name. Specifying both a name and number does broadly the same but forces the app to import by the specified number. Finally, specifying NONAME exports only a number. Am I on the right lines with all that?
Everything is correct. Ordinal once specified in DEF appears in LIB, and thus, becomes a sole criterion for entry resolution while loading exe. This never means that app linked with differently formed .lib, which instructs to import entry by name, will fail to load the DLL. Just because the DLL has the name exported as well.
Another little sample. Two EXEs are built with two different .lib files, one instructing to import by name, and another doing by ordinal. With both the EXEs both DLLs can be used interchangeably (I mean, of course 26dll_ord.dll should be renamed to 26dll.dll).
Last edited by Igor Vartanov; January 5th, 2012 at 03:37 AM.
Thanks again Igor. I had a loose understanding of this, right at the start but now I feel my understanding is much better. Just to clarify one thing for you...
Originally Posted by Igor Vartanov
Where can you see a contradiction?
I don't mean in this thread. I was talking about information I'd read on other sites.
"A problem well stated is a problem half solved.” - Charles F. Kettering
As far as I understand, a DLL's exported function table can contain either function names or ordinal numbers (perhaps both).
There are actually few tables in export section making 1) an index of function relative addresses, which you can take as 'ordinal to RVA', and 2) an index of function names to ordinals (physically comprised of two vectors of the same size), referencing the previous table. That's why it's possible to have both types of exports in the same DLL.
BTW, saving on name-to-ordinal resolution (linear search through names index!) to improve dll load time might appear to be another reason to use NONAMES.
Last edited by Igor Vartanov; January 5th, 2012 at 05:28 AM.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.