I am looking for a clean way to explicitly load library. Most often, I have a LIB and DLL pair so the LIB will handle all the "load stuff" and I can directly call the function in the dll. When doing this explicitly, I need to do sort of the following:
HMODULE libA = LoadLibrary("dllA.dll"); // NULL if load failed
HMODULE libB = LoadLibrary("dllB.dll"); // NULL if load failed
void (*functionA)(void) = libA ? GetProcAddress(libA,"functionA"):NULL;
void (*functionB)(void) = libB ? GetProcAddress(libB,"functionB"):NULL;
It will be messy if the LoadLibrary() and GetProcAddress() are found all over my code when I need to call function in DLL. I would like to know if there is a clean way such that I can write all the handling within 1-2 files and call the functions as if I am loading the library implicitly through LIB and DLL pair.
Indeed there is a way to get all the implicit linking convenience, while still being able to gracefully handle both library load as well as symbol lookup failures. Visual Studio offers Linker Support for Delay-Loaded DLLs, that give user code the ability to hook into the loader, and implement arbitrary recovery strategies for unavailable symbols (e.g. by returning a no-op stub). This makes it possible to consolidate all failure handling into a single place.
Write a pure interface to the external functions you need. (Platform dependent)
Provide an implementation class (for you platform). For your Windows implementation load the DLL, get the procedure address initially.
Than when the interface function need to be called, the class routes the call into the loaded DLL.
Use an similar way for other platforms.
This is nothing else than using of delay-loaded DLLs. It is just a manual solution. But the approach of using an interface allows you a real platform dependent solution.
Related
Is it somehow possible to run .exe without some of the (mainly 3rd party) dlls which may (or may not) be present? The reason for this is that if some of the drivers are not present, I want only to block using the HWs, not to block program execution.
For example: Run .exe which checks if there is desired .dll libraries and make action if not:
Warn user that some of the libraries are missing.
Forbid to use some part of code until the appropriate library is present.
I found out, that library checking is possible with function like this:
bool checkLibrary(std::string dllName) {
std::wstring stemp = std::wstring(dllName.begin(), dllName.end());
return LoadLibrary(stemp.c_str()) != NULL;
}
But when I run .exe, it shows me allways error, that .dll is missing. It looks like that OS or APP finds all dependecies before start of the .exe, but seems to be static linked. How link dlls dynamically when its functions is needed?
This is an option in Visual Studio. It's called Delay-Load Linking (/DELAYLOAD). By default, Visual Studio will set it up entirely for you, including the call to LoadLibrary.
Since you want to be notified about load failures, you'll need to set up a hook function. This will need to handle the dliFailLoadLib notification. Here you can show a custom error message, and set a "disabled" flag for your app's internal use.
Continuing with missing functions is a bit trickier. You'll need to handle more events though. If you set a "disabled" flag for internal use, you could just return &ExitProcessWrapper for each and every function that's not supposed to be called. This wrapper just calls ExitProcess(0), in case you overlooked something.
If you use headers you automatically link to library so on .exe loading it looks for that library. If you want to manually load DLL, you need to open it as you did and replace all calls by calls to place given by https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress
Suppose I have an application app.exe which does a load-time link to d.dll, which in turn does a load-time link to dangerous.dll. Suppose that dangerous.dll is considered to have various security vulnerabilities. Suppose also that none of the functionality in dangerous.dll is needed by app.exe, and app.exe does not make any calls to d.dll that require it to use any functions in dangerous.dll.
I want to distribute the app without dangerous.dll, and ideally with minimal or no modifications to app.exe or d.dll. If I just remove dangerous.dll, I get a loading error when starting app.exe because it loads d.ll and d.dll tries to load dangerous.dll, which fails.
Option 1
I could make a "no-op" version of dangerous.dll, that provided all the same export function signatures as dangerous.dll, but had no-op code for all the exported functions themselves. That might not be too bad. I wonder if there already exists a tool that can take a .dll file and output another .dll file that has the same export functions, but ones that do nothing? This has the disadvantage that my no-op version of dangerous.dll would still be visible to the user, and it would look like my application still has the vulnerabilities in dangerous.dll.
Option 2
I wonder if there is some way, without building d.dll from source, I could hack d.dll so that it does not attempt a load-time load of dangerous.dll. It would be okay if this caused any calls from d.dll to a dangerous.dll function to fail/crash, since as I say app.exe should not cause d.ll to use any of the functions in dangerous.dll.
If you have the source for d.dll, then just fix it to not load/use dangerous.dll.
If you don't have the source, just build a dangerous.dll with stub implementations for all exported functions.
Case closed. Move on and spend your time on more productive stuff.
I'm trying to build a project. I have a.lib file that I need to use in my project. I know that there are two ways to use this lib:
add it using #pragma comment(lib, "a.lib")
add it to linker dependencies Configuration Properties -> Linker -> Input -> Additional Dependencies
Now, a.lib uses StackWalk64 function DbgHelp. This library is supplied as DbgHelp.lib and DbgHelp.dll. I know that I can use it as a lib using two ways listed above. But what if I don't want to include it into my project and want to use DbgHelp.dll, how can I do that in Visual Studio?
If you want to call a function that is within a DLL, but don't want to link to the LIB file that imports these functions for you, then you can use LoadLibrary and GetProcAddress. (Though if you have the import library and can link to it, why do you want to load these functions manually?)
IF YOU HAVE THE DbgHelp.lib IMPORT LIBRARY, USE IT! LOADING FUNCTIONS MAUNALLY IS ERROR-PRONE IF NOT DONE RESPONSIBLY. USE WITH CAUTION!
// Type definition for a function pointer that can call the function
typedef BOOL (WINAPI *StackWalk64_func)
(
DWORD,
HANDLE,
HANDLE,
LPSTACKFRAME64,
PVOID,
PREAD_PROCESS_MEMORY_ROUTINE64,
PFUNCTION_TABLE_ACCESS_ROUTINE64,
PGET_MODULE_BASE_ROUTINE64,
PTRANSLATE_ADDRESS_ROUTINE64
);
// Within a function . . .
HMODULE hDbgHelpDll = LoadLibrary(TEXT("DbgHelp.dll"));
if (hDbgHelpDll == NULL)
{
// handle error and return
}
StackWalk64_func funStackWalk64
= (StackWalk64_func)GetProcAddress(hDbgHelpDll, "StackWalk64");
if (funStackWalk64 == NULL)
{
// handle error and return
}
// funStackWalk64 is valid and ready to use
Now you can call funStackWalk64 like the function StackWalk64, and pass the function pointer around the place. When you're done using the library, you should free the module handle:
FreeLibrary(hDbgHelpDll);
Please read up: http://www.learncpp.com/cpp-tutorial/a1-static-and-dynamic-libraries/
Implicit Linkage with an import library (using .lib)
In this case the static-library is an "import library", which automates the process of determining the effective functions in the DLL. This is called implicit dynamic linkage.
Explicit Linkage
If you don't want to use the import library you have to determine all functions by yourself, create corresponding pointers to the addresses of the procedures and use them after that.
Usually there's some InitDLL() function in your client code, which does this.
See: https://msdn.microsoft.com/de-de/library/64tkc9y5.aspx
The "GetProcAddress"-function can be used to obtain a handle to the function and call it.
This is called explicit dynamic linkage and requires also the calls to LoadLibrary() and FreeLibrary() on Windows.
More Info: http://www.equestionanswers.com/dll/what-is-implicit-and-explicit-linking-in-dynamic-loading.php
Explicit Linkage on Linux
For linux/unix things work differently. If you want to read up: http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
Usually (and in Visual C++ specifically,) the lib file that comes with a dll is what is called an "import library". It means that the library has no actual function bodies in it; it is just there to appease the linker and instruct it to generate an EXE (or DLL) that would use the first dll at load time.
It is so in this case too. Since you don't have access to the source code for DbgHelp so that you can build it as a real static library, you need to make do with the small import library at link time and the dll file at load/run time.
Note: the whole linking and dynamic linking concepts and mechanisms are obviously a lot more complex than what I have room here to discuss. So, the explanation above is quite narrow and specific to your question.
When I want to call some Windows function, like MessageBox I can import it from user32.dll and call (with LoadLibrary and GetProcAddress). But there is also a static library that Visual C++ uses, so I don't need to manually load DLLs and functions. How do they work? Do they contain wrappers that call LoadLibrary/GetProcAddress every time I call a function?
The "static library" that you're referring to is actually an import library. This type of library contains records that tell the linker which library each function actually exists in, and doesn't contain any code itself. The linker creates import records in the executable, which the loader resolves at load time. This fixes up the addresses used at runtime so your code doesn't need to explicitly call LoadLibrary and GetProcAddress.
No, they just allow you to use static linking with DLLs. The executable file contain a list of functions that it needs from other DLL files, so when the executable file is loaded the loader parses this list and resolves each function with LoadLibrary and GetProcAddress, saving result to a static table (IAT, Imported Address Table). This is done only once. There is also the notion of "delayed load" of DLL, that will resolve the address only when the function is call for the first time, but it's rarely used.
In this way the lib file for a DLL contains just information needed to build that list (names of exported functions).
I have a 3rd party component that includes a .LIB and .DLL file. In order to use the component I link the .LIB into my C++ program, and distribute the .DLL with application. The functionality provided is very specific, and only relevent to a small sub-set of my users, but distributing the .DLL incurs a license fee.
One work around here is to have two versions of my app, one which links in the 3rd party component, the other that doesn't, but I'd rather avoid the extra time involved in maintaining and distributing a second build.
Ideally, I'd like to simply exclude the .DLL from the distribution, but if I do this I get the error 'This application has failed to start because XXXXX.DLL was not found. Re-Installing the application may fix this problem'. Is this an exception that I can catch and deal with in my code? Alternatively, can I delay the loading of the .DLL until an attempt is made to call the specific functionality provided, and handle it then, or simply check for the existence of the .DLL and act accordingly?
The environment is VS 2003 and VS 2008.
There is no way to stop the binding after linked with the dll.
The only way that youo have is if you dynamically load the
dll during runtime.
Dll resolving is done before your exe starts running.
Code could look somehow like that.
If this does not work for your third party dll you could write an own dll that wrapps the third party dll and which can be loaded dynamically at runtime.
HINSTANCE lib = LoadLibraryEx("C:\dlls\thirdparty.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if(0 != lib) {
// Dll is present so use it
typedef CObj ( __cdecl *tFunction ) (const wchar_t*, const int&);
tFunction functionEntry = (tFunction)(GetProcAddress( lib,"EntryFunction"));
assert(0 != functionEntry);
// call the function
CObj obj = functionEntry(L"Hello", 1);
}
else {
// dll not present
}
Update: Please make sure that you use fullpath to your dll to make sure not any dll is pulled that has this name.
Visual Studio has support for delay-loaded DLLs. Using this functionality, a DLL is loaded when you call a function from that library for the first time. But you should check the license of your component to see if that's allowed.
You could load the DLL dynamically using the LoadLibrary() API function
But then you must use the GetProcAddress() on every function exported by the DLL that your application needs to call.
You could use LoadLibrary function to explicitly load DLL and the check the result. If successful then use GetProcAddress to find your CreateMyInterfaceImpl function. Otherwise use fake implementation of your interface or don't use it at all.