How to understand .def files? - c++

LIBRARY Vcam.ax
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
The above is from Filters.def, what does it actually do?

See MSDN:
Module-Definition (.def) Files
Exporting from a DLL Using DEF Files
About PRIVATE, they say this:
The optional keyword PRIVATE prevents
entryname from being placed in the
import library generated by LINK. It
has no effect on the export in the
image also generated by LINK.
In other words, those functions are hidden from the DLL's table of entry points and reserved for the OS.

The .def file on Win32 describes what functions get exported from a DLL. Unlike with .so files on gcc/Linux, where every symbol gets exported by default, you have to tell the compiler what functions to export. The standard way is to list it in a .def file. The other way is to use __declspec(dllexport) with Visual C++ (where using decorated function names would be no fun to use).
There are some keywords to place after the function name; you can speficy an ordinal number, that it shouldn't be exported by name (good for hiding your function names), or that it is private.
The documentation on MSDN describes the complete format:
Module-Definition (.def) Files

Related

Determining symbol names of the DLL

I have worked with "CPPLoadLibrary" example (from Microsoft All-in-One framework)
Okay, there are two ways of export symbols from the sample DLL.
Export symbols from a DLL using .DEF files
A module-definition (.DEF) file is a text file containing one or more module
statements that describe various attributes of a DLL. Create a .DEF file and
use the .def file when building the DLL. Using this approach, we can export
functions from the DLL by ordinal rather than by name.
Export symbols from a DLL using __declspec(dllexport)
__declspec(dllexport) adds the export directive to the object file so we do
not need to use a .def file. This convenience is most apparent when trying to
export decorated C++ function names.
And so we have the following code.
typedef int (_cdecl* LPFNGETSTRINGLENGTH1) (PCWSTR);
typedef int (CALLBACK* LPFNGETSTRINGLENGTH2) (PCWSTR);
LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)
GetProcAddress(hModule, "GetStringLength1");
LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)
GetProcAddress(hModule, "_GetStringLength2#4");
So my question is how to determine the name of symbol in order to call GetProcAddress?
in first case it's pretty straightforward, we take that symbol name from .DEF file.
But what about "_GetStringLength2#4"
What is underscore? What is "#4" stand for?
Thanks.
If you don't use a .DEF file, the export names are decorated according to their calling convention in order to support exporting overloaded functions. See Why can't I GetProcAddress a function I dllexport'ed?:
[T]he decoration scheme varies from architecture to architecture and from calling convention to calling convention. So, for example, if the function is exported from a PPC DLL, you would have to do GetProcAddress(hinst, "..SomeFunction"), but if it is exported from an 80386 DLL as extern "C" __stdcall, you would need GetProcAddress(hinst, "_SomeFunction#8"), but if it's __fastcall you would need GetProcAddress(hinst, "#SomeFunction#8").
What's more, C++ decoration varies from compiler vendor to compiler vendor. A C++ exported function might require GetProcAddress(hinst, "?SomeFunction##YGXHH#Z") if compiled with the Microsoft C++ compiler, but some other decorated string if compiled with the Borland C++ compiler.
So if you intend people to be able to GetProcAddress for functions and you intend your code to be portable to multiple platforms, or if you intend them to be able to use your DLL from a language other than C/C++ or use a C++ compiler different from Microsoft Visual Studio, then you must export the function by its undecorated name.
See The history of calling conventions, part3 for a description of the various name decoration schemes. In this case, the function uses the __stdcall calling convention, so it's decorated by prepending an underscore and appending a # sign and the number of bytes worth of parameters it takes. It takes one word-sized argument for a total of 4 bytes, so it's decorated as _GetStringLength2#4.
To answer your actual question, use your compiler's TDUMP or similar tool, or any other tool that can display an executable's exports table, so you can see the actual exported names.

Exporting static lib symbols from DLL

I'm using a Facade DLL to a static lib. The Dll provides a small interface and resource management to be shared across multiple DLLs. The Dll-Header do expose stuff from the static library:
class DLL_EXPORT MyDllClass {
public:
/// ...
OneStaticLibClass * ptr;
};
The Problem is: if this should works I've to link the StaticLib to the DLL and the application using DLL. I didn't manage to export parts of the StaticLib correctly. I tried in the export headers:
class DLL_EXPORT OneStaticLibClass;
but that doesn't work... I still get:
undefined reference to OneStaticLibClass::~OneStaticLibClass(void)
undefined reference to OneStaticLibClass::operator<<(char const *)
Andy ideas how I can export parts of the static library with the DLL?
Thank you!
You will need to create a .def file and pass it to the linker. DLLEXPORT is not necessary in this case.
The reason for this is the way symbols are resolved when using a static library. When you create a DLL, only those symbols needed by the DLL itself are searched, and object files containing these symbols are copied into the DLL. If the DLL code does not reference your destructor, it will not be included.
A .def file will tell the linker which functions are exported. Exported functions will be searched and pulled from the static library.
One downside of this process is that you need to use mangled C++ names in the .def file. Mangled names can be obtained with the dumpbin utility.

Why does Implicit DLL Linking need relevant Lib file but Explicit Linking does not?

In a Windows environment,
When I tried to link a DLL to my program Explicitly (using LoadLibrary),
First I need to define the function pointers according to each
function signature inside the DLL.
Then get the function addresses using 'GetProcAddress' and assign them to those pointers.
When I tried to link the DLL to my program Implicitly (using header file)
First it need the relevant header file to get function signatures.
Then it needs the relevant Lib file that was generated with the DLL.
My questions are
Why does implicitly linking need a Lib file as well?
What information does it need to retrieve from 'Lib' file that it cannot get from the DLL or Header file?
If there is something for question 2, how is information retrieved when explicitly loading?
I've already gone trough this question. But I cannnot understand any worthy reason.
Please, could someone help to explain this in simple terms. Thank you.
Why Implicitly linking need Lib file too.
The .libs have the import information of the dll, you can check the information using the dumpbin command that is included in Windows/Visual Studio SDK.
This is the link information of recv inside ws2_32.lib for example:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 4907F6ED Wed Oct 29 01:38:53 2008
SizeOfData : 00000014
DLL name : WS2_32.dll
Symbol name : _recv#16
Type : code
Name type : ordinal
Ordinal : 16
You can check there is the ordinal and the name inside ws2_32.dll (check that now it says to import a DLL).
What information it need to retrieve from 'Lib' file that cannot get from DLL or Header file
In the header file, there is no information from where to extract the imports, so them are marked as imports (__imp__name) when compiled, and when it's linked against the .lib, it resolves the name:
If it's inside the .lib it just links against it.
But if there is information on external reference (DLL), it will construct the import inside the import table so it's loaded dinamically.
If there is something for question 2, How those information retrieve when explicit loading.
If for explicit loading you mean the LoadLibrary, you are telling it at runtime and not at link time. So the PE loader will search the DLL inside the PATH and will load it dynamically. Then you have other functions to get the exported functions addresses.
If you don't understand something just ask me, try playing with dumpbin and read about PE if you want to understand this better.
When linking implicitly, the function declaration specifies the name to be used in the program, and the prototype and calling convention. But more information is needed. Specifically:
The fact that the function is implemented externally in a DLL.
The name of that DLL.
The exported name of the function. That is the name used to export the function from the DLL which may not be the same as that used when you import it.
Some language designers chose to provide this information using language extensions. For example Delphi took this route. Implicit linking is specified entirely in code with no .lib files. On the other hand the convention for C and C++ is to use .lib files to specify the missing information.

When building a dll, can the lib be used for linking?

I wanted to create a C++ dll (to be used in a dot net application). Some functionality I needed was already implemented in another C++ dll.
The dll I was referencing was set up like this (including the comment):
extern "C"
{
__declspec(dllexport) BOOL SomeFunctionToBeUsedExternally();
}
// internal functions
BOOL OtherFunctions();
I need to use one of the OtherFunctions in my code.
So, I added the proper include in my own code, added dependencies on the lib created by the dll above, and used the method I needed. As a result, of course, I got another __declspec(dllexport)... function.
It refused to link though, I got an error about the OtherFunction.
I verified everything, looked online - nothing seems to solve my problem.
Then, I added a __declspec(dllexport) in front of the function I needed, and it works.
I don't understand though. I thought, the dllexport marked functions will be exported to the dll, but aren't all functions sent to the lib ?
Why do I have to export functions to the dll, if I am not linking against the dll but against the lib ?
No, the linker does not automatically export all identifiers. The dllexport attribute tells the linker which identifiers are exported. Without this you would be forced to either export every identifier in the DLL or specify which identifiers should not be exported. When the linker creates the DLL it also creates an import library and includes information about which identifiers are exported based on that attribute.
When you want to use a DLL you need link with the appropriate .lib file for good reason. The .lib file tells the linker which identifiers are exported, the name of the DLL they are in and other information. It is also possible to export identifiers from the DLL by ordinal instead of by name. In this case the linker still needs to match the identifier with the appropriate ordinal. This is only possible by having an accompanying library file that contains that information since it is not present in DLL's export table.
No, only exported functions end up in the .lib. As you can tell.
It is not a static link library, it the import library for the DLL. It is a very simple and very small file since it contains no code at all. Just a list of the exported functions. The linker needs it to resolve the external in the client code, it needs to know the name of the DLL and the actual exported function name or ordinal (could be different) so it can add the entry to client's import table. Import libraries having the same filename extension as static libraries was perhaps a bit unfortunate.

How do I create an import .lib that would contain the __imp__ symbols?

We have an external DLL that we don't have an import lib for, and we have header files that declare functions from that DLL.
Some of those functions are declared with __declspec(dllimport), others aren't. If the attribute weren't used, we could simply create the import library by writing a .def file and running the lib tool. However, functions that are declared with the attribute require special symbols, e.g. function foo would require __imp__foo.
Is there a simple way to create an import .lib that would contain the __imp__ symbols, preferably without writing a stub function for each export and generating a fake DLL?