Altering DLL search path for static linked DLL
My first thought is, if you are statically linking a dll, it isnt a plugin. Just put the dll in the EXE folder and be done with it. That is the deployment configuration supported by windows for statically loaded DLLs.
That said, there are ways to achieve what you want. But they are mostly stupid, or complicated for no good reason: Your options are:
- Don't statically link. Use LoadLibrary("plugins/Plugin.dll") & GetProcAddress to access plugin content.
- Add "the path to your plugins folder" to the systems PATH environment variable.
- Use the delay load mechanism to delay accessing the plugins functionality, set a custom helper function that can load the dll(s) using a provided path.
- Turn the plugins folder into an assembly (by creating a .manifest file in it that lists the plugin.dll). Add "plugins" as a dependent assembly to your app. Now it will look in the plugins folder.
- Split your application into a stub exe and a dynamically loaded part. In the stub exe call SetDllDirectory to point to the plugin folder, then call LoadLibrary passing the full path to "appstub.dll".
To turn a folder, with one or more dll's into an "assembly", simply add a file to the folder with the folders name.manifest.
So, plugins.manifest :-
<assembly manifestVersion="1.0">
<assemblyIdentity type="Win32" name="Plugins" version="1.0.0.0" processorArchitecture="x86" />
<file name="Plugin.dll"/>
</assembly>
It is a VERY good idea to ensure that the folder and the dll's name is different as if the dll name is the assembly name windows starts looking at its embedded manifest file for information about the assembly.
Assuming you are using Visual Studio 7 or later, the following directive added to a .c/.cpp or .h file in the project will then make your application attempt to load dlls from the assembly rather than just the local directory:
#pragma comment(linker, "/manifestdependency:\"name='Plugins' "\
"processorArchitecture='*' version='1.0.0.0' "\
"type='win32'\"")
Search path for a DLL referenced by a plug-in DLL
The idea I outlined in the last comment to my question turned out to be a good one.
I changed myplugin.dll
to be a simple shim DLL. The entry point of that shim performs the following operations:
- It first loads
other.dll
(usingLoadLibrary
) from the directory containing the shim,plugins\myplugin\
in my case. - It then loads
myplugin-impl.dll
, the "real" plug-in, from the same directory.
myplugin.dll
then simply forward all calls to myplugin-impl.dll
which does the actual job.
Note that myplugin-impl.dll
still links implicitly to other.dll
. However, when myplugin-impl.dll
is loaded, other.dll
has already been loaded by the shim in the address space of the application's process so no further loading occurs.
With this solution, we get the benefits of implicit DLL loading (in particular loading C++ classes with virtual methods) while still having full control on where the implicitly-loaded DLL is loaded from and how it is loaded.
C++ set dll search location
If you use load time linking then you need for the DLL to be located in the DLL search path. That is documented here: Dynamic-Link Library Search Order. Typically this would require that you add the DLL folder to the PATH
environment variable. Now, adding a folder to the PATH
environment variable is heavy weight solution to a problem. You surely don't want to do that.
On the other hand, if you switch to run time linking then you can pass the full path of your DLL to LoadLibrary
. You can call GetModuleFileName
to find the file name of the executable, and then pull out the directory, and add \libs\MyDll.dll
. But the big downside of run time linking is that you need to use GetProcAddress
for each function that you import.
Neither of these options is particularly attractive. My advice would be to change your proposed design. Put all the DLLs that the executable needs into the same directory as the executable.
How do I specify the .DLL search path for an MFC .EXE?
THERE IS NO ANSWER
In order for my "answer rate" to be acceptable to those out there who only look at numbers (not the actual answers), I'm answering my own long-outstanding-unanswered questions as "there is no answer" (if one shows up, I'll definitely choose their answer as THE answer).
How to set dll search path in Fortran?
As discussed, for Windows:
- add the place of the dll to the
PATH
variable.
In case one wants to only set the path to the dll
temporarily:
- create a
.bat
file with:- save current path:
set SAVED_PATH=%PATH%
- set path including dll directory:
set PATH=<path to dll>;%PATH%
<run executable>
- reset path:
set PATH=%SAVED_PATH%
- save current path:
Related Topics
How to Read the Results of a System() Call in C++
How to Know If One Shared Library Depends on Another Shared Library or Not
Hide or Crop Overlapping Text in Qlabel
Overriding a Base's Overloaded Function in C++
Redirecting Cout to a Console in Windows
Floating Point Equality and Tolerances
Differencebetween Std::Array and Std::Vector? When Do You Use One Over Other
Class Template with Template Class Friend, What's Really Going on Here
Effective C++ Item 23 Prefer Non-Member Non-Friend Functions to Member Functions
String Conversion with Boost Locale: Different Behaviour on Windows and Linux
System("Command") Produces an Error; But It Works When Invoked Directly from Bash Prompt
Does "Const" Just Mean Read-Only or Something More
Why Istream Object Can Be Used as a Bool Expression
Using \ in a String as Literal Instead of an Escape
Efficient Unsigned-To-Signed Cast Avoiding Implementation-Defined Behavior