[osg-users] delay-loading OSG DLLs?

Christian Buchner christian.buchner at gmail.com
Wed Oct 26 03:49:57 PDT 2016


Hi, here is my code that actually enables the delay loading to function.
First I modify the PATH environment variable to actually contain the
folders where the DLLs are expected to be found.

Then using __HrLoadAllImportsForDll() I get all the import symbols from the
delay loaded DLLS (which have to be given explicitly, file by file) which
allows OSG to run successfully.

Without that second step, no graphics context could be initialized.

The only remaining issue is that in case a delay-loaded DLL isn't found at
runtime, the function __HrLoadAllImportsForDll() crashes internally
somewhere, and not even the try{} catch {} block can prevent this. I wish I
could somehow catch this.

#include <regex>
#include <string>

#include <Windows.h>
#include <LibLoaderAPI.h>
#include <DelayImp.h>


        // the DLL search paths to prepend to PATH
        std::vector<std::wstring> path_list = {
L"%CD%\\..\\deps_v2\\OSG-3.4\\bin",
L"%CD%\\..\\deps_v2\\OSG-3.4\\3rdParty\\bin" };

        // prepend the PATH environment variable with the folders specified
above
        wchar_t pwd[512];
        _wgetcwd(pwd, sizeof(pwd) / sizeof(wchar_t));
        std::wstringstream ss;
        for (auto path : path_list)
        {
            // replace %CD% with the actual current working directory
            path = std::regex_replace(path,
std::basic_regex<wchar_t>(L"\\%CD\\%"), pwd);
            ss << path << ";";
        }
        ss << _wgetenv(L"PATH");
        ss << '\0';
        const std::wstring env = ss.str();
        SetEnvironmentVariable(L"PATH", env.c_str());

        //
        // Delay-load all import symbols from the OSG DLLs now.
        //

#if _DEBUG
        std::vector<std::string> dll_list =
        { "osg130-osgd.dll", "osg130-osgDBd.dll", "osg130-osgViewerd.dll",
"ot20-OpenThreadsd.dll" };
#else
        std::vector<std::string> dll_list =
        { "osg130-osg.dll", "osg130-osgDB.dll", "osg130-osgViewer.dll",
"ot20-OpenThreads.dll" };
#endif

        for (auto dllname : dll_list)
        {
            fprintf(stderr, "Delay-loading imports from %s\n",
dllname.c_str());
            bool failed = true;
            try {
                failed = FAILED(__HrLoadAllImportsForDll(dllname.c_str()));
            }
            catch (...)
            {
            }
            if (failed) {
               fprintf(stderr, "Delay-loading imports from %s failed!\n",
dllname.c_str());
                exit(1);
            }
        }

        init = true;
    }




2016-10-25 19:24 GMT+02:00 Christian Buchner <christian.buchner at gmail.com>:

> Hi,
>
> I was wondering if anyone of you has successfully used the /DELAYLOAD
> linker option with the OSG DLLs on Windows.
>
> For me, attempting this causes the creation of the graphics context to
> fail, because
> windowingSystemInterfaceRef() called by createGraphicsContext() returns an
> invalid reference.
>
> Any clues about how to fix this possibly? It seems that maybe constructors
> for static objects inside the OSG DLLs aren't getting called as required.
>
> Christian
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20161026/c056a548/attachment-0003.htm>


More information about the osg-users mailing list