add custom DLL search path @ application startup

落爺英雄遲暮 提交于 2019-12-05 02:23:05

I found Matthew's answer worked for me.

In visual studio 2012 goto your project properties and in Configuration Properties->Linker->Input->Delay Loaded Dlls add each dll file that you want to not load until needed.

Although it no longer needs to run before main, this is my code to set the new search path

class RunBeforeMain
{
public:
    RunBeforeMain()
    {
        const TCHAR* dllPathEnvName= name of env variable to directory containing dlls
        const TCHAR* pathEnvName= TEXT("Path");


        TCHAR newSearchPath[4096];
        ::GetEnvironmentVariable(dllPathEnvName, newSearchPath, MAX_PATH);

             //append bin
        _tcscat_s(newSearchPath, MAX_PATH, TEXT("bin;"));
        size_t length = _tcslen(newSearchPath);

            //append existing Path
        ::GetEnvironmentVariable(pathEnvName, newSearchPath + length, 4096-length);
        ::SetEnvironmentVariable(pathEnvName, newSearchPath);

    }
};
static RunBeforeMain runBeforeMain; //constructor code will run before main.

[Edit - after re-reading the question I see that the problem you're having is that the DLLs are getting loaded before main starts]

I'm guessing that those libraries are written in C++ and are loading the DLLs from the constructor of some objects in global scope. This is problematic. Allow me to quote Yossi Kreinin:

Do it first thing in main(). If you use C++, you should do it first thing before main(), because people can use FP in constructors of global variables. This can be achieved by figuring out the compiler-specific translation unit initialization order, compiling your own C/C++ start-up library, overriding the entry point of a compiled start-up library using stuff like LD_PRELOAD, overwriting it in a statically linked program right there in the binary image, having a coding convention forcing to call FloatingPointSingleton::instance() before using FP, or shooting the people who like to do things before main(). It’s a trade-off.

[Original answer below]

See this page for the search algorithm used for loading DLLs. You can use SetDllDirectory() to add a directory to the DLL search path.

You also should be able to add a directory to the PATH environment variable using GetEnvironmentVariable() and SetEnvironmentVariable().

Another option is to change the current working directory to the folder containing the DLLs with SetCurrentDirectory(). Just make sure to change the working directory back after loading the DLLs if you ever load any files using relative filenames.

My recommendation is to use delayload linking for the DLLs and call SetDllDirectory() early enough so it can find them when the methods/functions are invoked.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!