Delay Loading DLLs






2.43/5 (7 votes)
Jan 12, 2003
2 min read

117745

1014
Easy to use library which let you use different compilers, to optimize-compile your DLL for different processors
Introduction
This is a easy to use library which let you use different compilers, to optimize-compile your DLL for different processors.
Details
Move all the to be optimized classes and functions to a DLL, and the DelayLoader library will automatically import all the functions from the fastest (for this processor available) DLL.
There are 4 projects included:
- DelayDLL, a library project which is the one to use in your own workspaces
- MainDLL, a sample DLL which exports a function
- Test, a sample DLL which exports a function
- MainMFC, a sample project which makes uses of the projects above, no fancy
MessageBox
, just step through with debugger to see which DLL is loaded. ATRACE
output is done, so you can easily see which DLL is currently loaded
The library is based on the Delay loading of DLL. So we start loading the DLL
when it is needed for the first time. No LoadLibrary
and GetProcAdress
functions need to be called, The Delay Loading from Microsoft takes care
of this.
With a specific hooking mechanism we can force our app to load a different DLL than compile-time was programmed. We could even get the adress of a different named function. The DelayDLL.dll should be loaded by the MainMFC program, but because we run this program on my Athlon MP the DelayDLL.Athlon.dll file is loaded.
This hook makes it very easy when we build a program which should make use of
processor specific optimizations. The UnloadDelayedDLL( LPSTR )
method can
unload a DLL at runtime, to
free up memory, for if you don't have 1Gb of RAM like me :-p
Hope this is useful for you guys.
How to use
- Add the DelayDll project to your workspace.
- Set a dependency for your project to this project, the library will
automatically be linked against your exe.
OR
Add the precompiled library delaydll.lib to your DLL's configuration. - Add a new file to your project, so you can easy change / add new DLLs (See below.)
- Make a copy of the configuration
- Build->Configuration
- Select the DLL-project you want to optimize,
You could only add a copy of Win32 Release, and call it w32 Athlon Rls. Or also make a copy of the win32 Debug, and call it w32 Athlon Dbg. The only thing you have to change in the project settings, is on the link tab, the Output name, to MainDLL.Athlon.dll for example.
And of course you should select another compiler, for this configuration ( using the Codeplay Compiler Controller Plug-in ). Or make some assembler files yourself and use them for this configuration. For now only compile the .c files using VectorC, so not the complete project. ( no cpp support yet ). Of course you can also use the Intel compiler to create optimized DLLs.
Here is an example of file to be added to your project, which will make use of the optimized DLLs.
// <START OF FILE : MyDelayDlls.cpp> /******************************************************************/ /* Sample .cpp file, to include in your executable */ /******************************************************************/ #include "..\DelayDll\DelayDll.h" // Tell delay loader to call my hook function SET_DLIHOOK_PROC /*****************************************/ /*Which DLLs should be Delay loaded */ /***************************************/ // Use Upper and Lower case letters, exactly the same as in de DLL // Project ,Thanks to MS DelayLoader :-( #pragma comment(linker, "/DelayLoad:Test.dll") #pragma comment(linker, "/DelayLoad:MainDLL.dll") // Descriptor for Test.dll // value nr,Description // 1InUse, always 1, for the last in line, use 0, so library known array // is ended. // 2DllName, use this if your optimized DLL has a complete // different name than your original DLL // 3DllExtension, if you use an extension, Original:Test.dll, // Optimized:Test.Pentium.dll // 4Optimized for Processor, A PIV dll, will not be loaded on a PIII // 5Used Compiler, not used, but maybe we ever want to know this?? DLLDescriptor TestDLL[] = { 1,NULL,"Pentium.dll",DELAYDLL_PROC_PENTIUM,DELAYDLL_COMP_INTEL, NULL }; // Descriptor for another DLL DLLDescriptor MainDLL[] = { 1,"MainPIV.dll",NULL,DELAYDLL_PROC_PIV,DELAYDLL_COMP_VECTORC, 1,NULL,"Athlon.dll",DELAYDLL_PROC_ATHLON,DELAYDLL_COMP_VECTORC, 1,NULL,"PII.dll",DELAYDLL_PROC_PII,DELAYDLL_COMP_VECTORC, NULL }; // Only these DelayLoaded DLL will be checked for there Optimized versions // value nr,Description // 1Dll name, (case sensitive) // 2Use this Descriptor struct // ( All DLLs, could have the same Descriptor struct, // ONLY when Extensionname is // used and not a fullname ) DLLCollection pDelayLoadedDLLs[] = { "Test.dll", TestDLL, // Tries to load first : Test.Pentium.dll, then Test.dll "Test2.dll", TestDLL, // Tries to load first : Test2.Pentium.dll, then Test2.dll "MainDLL.dll", MainDLL,// Tries to load first : MainPIV.dll, then MainDLL.Athlon.dll, // then MainDLL.PII.dll, then MainDLL.dll NULL }; //<END OF FILE>