Link to home
Start Free TrialLog in
Avatar of cjm 32
cjm 32

asked on

In C++ application, Wait until runtime to choose the path to the openGL32.dll that is called.

In C++ application, I want to wait until runtime to choose the path to the openGL32.dll that is called. There are two possible paths: path #1 is the path to the directory in which the application resides (which is in the Program Files (x86) directory; path #2 is the system folder. Just having the openGL32.dll present in the application's directory results in it being called. I'd like to have the option of continuing to leave the openGL32.dll in the application directory, but just NOT call it but instead use the openGL32.dll in the System directory.

I've tried a couple approaches and neither of them work thus far. So, here is some additional info:

In the project settings, I am linking against opengl32.lib,, glu32.lib, and glaux.lib. Also in the project settings, I have listed openGL32.dll under the "Delay Loaded Dlls" field.  In my application's InitInstance(), I have tried calling SetDllDirectory("C:\\Windows\\System32\\openGL32.dll"); however, even though this function returns TRUE, the openGL32.dll that resides in the application's directory STILL GETS LOADED AND USED.

I've also tried calling LoadLibrary("C:\\Windows\\System32\\openGL32.dll") from IniitInstance(), thinking this would "force" the system version to be used; however, even though this function returns a valid handle to the dll, the openGL32.dll that resides in the application's directory STILL GETS LOADED AND USED.

I've also tried a quick and dirty approach of moving the openGL32.dll out of the application's directory, which would then "force" the openGL32.dll in the System folder to be used; however, due to permissions issues with out users (not being given permission to delete/move files from the application directory, this is not the preferred approach.

Any help would be greatly appreciated!!!
Avatar of Zoppo
Zoppo
Flag of Germany image

Hi cjm 32,

I don't think this is possible as long as the DLL is in the same path as the program's executable. As shown at https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order in any case the DLL is first searched in the directory from which the application loaded:
The SetDllDirectory function supports an alternate search order if the lpPathName parameter specifies a path. The alternate search order is as follows:
  1. The directory from which the application loaded.
  2. The directory specified by the lpPathName parameter of SetDllDirectory.
  3. The system directory.
So I would guess it could work if you move the DLL from the apllication's directory (i.e. to a subfolder) at build time (not at runtime as you mentioned) and to use SetDllDirector if you want to load it from there.

BTW: You must be aware that doing this (if it works at all) could cause problems - I'm not very familiar with the OpenGL-DLLs, but what you plan to do is to use a DLL for implicit delayed loading which may or may not fit to the LIBs you linked into your application. This means that if a function is used which has different function signature in the two DLLs or only exists in one of the two DLLs the apllication will produce runtime-errors or crashs or anything.

Best regards,

ZOPPO
Hi,
You can't bypass the DLL loading process, unless you provide your own implementention, wich is nowhere near a trivial task.
Avatar of cjm 32
cjm 32

ASKER

I've now tried the following:

a) In the project settings for my application, I've listed the openGL32.dll under the field "Delay Loaded Dlls".
b) I've deleted the openGL32.dll from my application's directory in Program Files (C:\Program Files (x86)\MyApplication)
c) I've put a copy of openGL32.dll into my application's folder in the Public directory (C:\Users\Public\Documents\MyApplication)
d) In my application's source code, in the application constructor, I'd added the following two calls:
   bResult = SetDllDirectory("C:\\Users\\Public\\Documents\\MyApplicationr\\OPENGL32.DLL");
   hLibrary = LoadLibrary("C:\\Users\\Public\\Documents\\MyApplication\\OPENGL32.DLL");

bResult is TRUE;
hLibrary is a valid (not NULL) pointer.

So, with all of the above in place, I successfully get the OPENGL32.DLL in the public directory to be loaded at runtime.This is good.

HOWEVER, using Process Explorer, I see that OPENGL32.DLL in the system directory (C:\Windows\SysWOW64\openGL32.dll) is ALSO being used by my application. This is bad. This is what I'm trying to avoid, by loading the copy of openGL32.dll that I've positioned in my application's Public folder.

So I feel like I'm half way to the finish line on this. I'm gettinga dll to be loaded by setting the path to it at runtime, but the dll in the system folder is also jumping into the fray. I was under the impression that ONLY ONE dll of a given name could be loaded into memory per process. But I'm seeing TWO openGL32.dlls in my application's process.
Hm ... I think that if this could work at all you shouldn't need to load the DLL with LoadLibrary.

'I was under the impression that ONLY ONE dll of a given name could be loaded into memory per process ' - no, that's not the case. This is true only for one and the same DLL (the same file), but not for different DLLs, even if their file name is equal.

BTW, I think this is wrong:
bResult = SetDllDirectory("C:\\Users\\Public\\Documents\\MyApplicationr\\OPENGL32.DLL");

Open in new window

SetDllDirectory expects a path to a directory, not to a DLL

Anyway, it may be there's a better way - after I searched some more time I found there's some helper functionality which can be used to hook into the delay-loading process: https://docs.microsoft.com/de-de/cpp/build/reference/understanding-the-helper-function?view=vs-2019

I never used this, but if I understand it correctly it shouldn't be too difficult (and it's not needed to play around with SetDllDirectory), it's just implementing a small function which loads the DLL and kind of regeristing it via a global function pointer:
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
 ...
}

// 
const PfnDliHook __pfnDliNotifyHook2 = delayHook;

Open in new window


Here I found a small sample which uses this kind of hook to load a DLL delayed from a different path: https://devblogs.microsoft.com/oldnewthing/20170126-00/?p=95265

I hope this helps,

best regards,

ZOPPO
Something weird:

Why don't you use standard mecanics ? Like compile your application with openGL library, and provide your DLL with your application.
Or compile statically and don't worry about the DLL anymore since the library will be embeded within your application.

To my knoweldge, windows look for DLL as follow:
If a path is given, use it.
Else, look in the application's directory.
Else look in the system directory.
Else, fail.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.