I feel like there's a much, much better way than just having hundreds of signatures in typedefs, and then loading pointers by GetProcAddress. As far as I know, it is the easiest -- but dirty -- when it comes to loading DLL functions.
Is there a less messy way to load DLL functions? Specifically, a large amount of Winapi and Tool Help library functions? I know you can just "include a .lib," but I feel like that would cause unnecessary bloat; nor do I have access to the source code (although Jason C mentioned it is possible to go from a .dll to a .lib).
I was looking to code a library for this. I feel like the major roadblock is dealing with functions that have varying signatures; or is this precisely the reason why everyone uses typedefs instead of "some fanciful loop" to load their DLL functions?
Visual C++ has an option to delay load a DLL. Your code you links in the DLL's lib file, includes its headers, and call the functions as normal. The Visual C++ linker and runtime take care of calling LoadLibrary() and GetProcAddress() the first time a function is called.
However this will cause a runtime exception if the DLL cannot be loaded for any reason, rather than causing your application to fail to load as with a normally linked DLL.
If this DLL is always loaded and required by your application to run, then you should like to the DLL normally (using the .lib file). In that case you are gaining nothing by delay loading the DLL in that case.
There should be a function provided to load a dll manually given it's file name. In the windows API it's LoadLibrary(). It's generally not used unless you're developing a "plugin" style application or you need to manually control loading and unloading.
You should consider how your code will be used to determine if a static library or a dynamically loaded dll is the best solution for your requirements.
Creating a class as a wrapper of dll, where the public member function of the class are nothing but pointer to that of functions in dll obtained by get proc address would be one fine way to load functions from dll.
It would be better to use RAII ability of c++ to free libraries loaded by freeing libraries in destructors of the class.
This:
Can be achieved like this:
Where the class DllHelper is:
All credits to Benoit
I can't find a more elegant way than this.
Your functions have to be declared somehow, so you need the function signatures. But, if you feel you are duplicating the function signatures, you can use
decltype(&func_name)
to eliminate that duplication (given a functionfunc_name
with the same target signature). You can wrap that in a macro to make it more palatable.Another common approach is to shove all the function pointers into one big struct (or a bunch of task-specific structs), and load a pointer to the struct instead (e.g. by loading a function that returns a pointer to the struct). This looks like the following:
Common header
DLL
Program using the DLL
There are several different ways of loading Windows libraries, but each way serves a different purpose.
Using
LoadLibrary()
andGetProcAddress()
manually is intended to allow runtime decisions about several different dynamic linking situations. These calls are simply system calls which do not affect any aspect of the resulting PE file whatsoever, and the addresses returned byGetProcAddress()
are not special in any manner with regards to code generation. This means that the caller is responsible for properly use these symbols at the very syntactical level (for example, using the proper calling convention and the correct number, size and alignment of the arguments, if any, for a function call).Linking against a
.lib
file associated with a.dll
is different. The client code refers to the runtime content using external identifiers, as if they were statically linked symbols. During the build process, the linker will resolve these identifiers with the symbols found in the.lib
file. While, in principle, these symbols could point to anything at all (as any other symbol could), an automatically generated.lib
file will simply provide symbols which act as tiny proxies to the memory content that will be filled at load time by the PE loader.The manner in which these proxies are implemented is dependent on the type of memory access expected. For example, a symbol which refers to a function in the
.dll
will be implemented as a single indirectjmp
instruction, in such a way that the originalcall
instruction from the client code will hit thejmp
instruction from the.lib
content and will be forwarded to an address resolved by the PE loader at load time. At this address reside the dynamically loaded function's code.Many more details aside, all of this is used to instruct the PE loader to do the same job as the client code would do by itself: call
LoadLibrary()
to map a PE into memory and dig through the export tables withGetProcAddress()
to find and calculate the proper address to every needed symbol. The PE loader does this automatically at load time from the information found in the import table of the client executable.In other words, load-time dynamic linking is slower and fatter than run-time dynamic linking by the tiniest amount, if any, but it is intended to provide a much simpler programming interface to the ordinary developer, specially because many libraries are always required and always available. Attempting to provide any additional logic through manual loading is not useful in these circumstances.
Summarizing, do not bother to use
LoadLibrary()
andGetProcAddress()
just because they seem to provide more performance or robustness. Link against.lib
files whenever possible.Going further on the topic, it is even possible to create PE images which don't contain any import tables at all (and can still access system calls and other exported routines). This approach is used by malware to hide suspicious API usage (such as Winsock calls) by stripping any load-time information.
The "bloat" of linking to a .lib file (by "bloat" I'm presuming you mean a few extra kB on the executable, which, ya know...) isn't "unnecessary" if you're using it for the convenience of avoiding dealing with hundreds of GetProcAddress calls. :)
Not quite sure what you mean by "some fanciful loop"; the typedefs used in this context serve a similar purpose to declarations in a header -- they provide the compiler and the human reader information about the signature of the function that is being called. One way or another, you have to provide this.
There are tools out there to generate a .lib from a .dll; but you'll still have to have a header declaring the functions you are calling so that the compiler knows what you're doing. Essentially, a .lib generated for a .dll is just a "stub" that loads the DLL and gets the function addresses for you. Different API, but essentially the same.
The only way around it is to design your DLL interface differently so that you don't have as many functions to deal with. However, in most cases I would not say that avoiding typedefs/declarations for functions is sufficient motivation to do something like this. E.g. you could expose exactly one function like (for example):
And have your implementation of PerformAction do something different depending on "action". That is certainly reasonable in certain situations that are unrelated to your post, but it is not really an appropriate "workaround" for the "problem" you are describing.
You pretty much just have to deal with it. Either create a header with declarations and generate a stub .lib, or create a header with typedefs and use LoadLibrary/GetProcAddress. The former will save you some typing. The latter lets you handle cases where the DLL is not present, or load DLLs that are unknown at design time (e.g. plugins as mentioned in another answer).