I've been updating a bunch of Win32 code in a utility library for West Wind Web Connection today when I ran into a realization that I had by accident introduced a dependency to the .NET framework into this non .NET application/tool. Some time ago I added a library that optionally provides the ability to call .NET classes (instance/static), access enums etc. from FoxPro without actually requiring COM registration of the classes.
The process uses code to host the .NET Runtime manually along with the ability to create AppDomain's and create instance types or access static members. All of this functionality is contained in Win32 APIs that are accessible through MSCOREE.DLL which is provided by the .NET runtime. I've been using this functionality to access all sorts of .NET functionality in a variety of tools and internal applications I have running here.
It works great, but I neglected to realize that this essentially added the .NET runtime as a dependency which in this case is not cool since this tool is used by a lot of rather old applications that simply might not have .NET installed. Heck the DLL runs on Win98 for that matter and I have customers that are still running on that (eeek!)...
The big problem is that the dependency is incurred as soon as the DLL is loaded, not when the actual functionality is accessed. So over the last few weeks I've been getting intermittent reports from some customers that the DLL failed to load with a generic load error. Duh!
Anyway long story short I panicked and started to pull out the small bit of wrapper Win32 code out of the DLL and stick it into a new project and compile into a new DLL. Just as I was done (surprise, surprise) I looked through various optimizations in the C++ project and I noticed this handy option in the Linker configuration:
Bite me! All this effort for nothing. This handy little option allows me with a simple linker switch to have DLLs delay loaded. I don't know in which version of Visual Studio this was introduced but that's a damn handy function. Setting the flag above and setting it to delay load mscoree.dll and I'm back in business with my original DLL and I've just wasted a half an hour setting up the new DLL project. Now when I load the DLL mscoree.dll no longer loads immediately - only when I actually access the .NET bridging code.
This beats the hell out of having to manually set up delay loading code in general as I've done in this particular DLL for a number of optionally supported third party tools (like DynaZip a LOOOONG time ago and more recently the GhostScript DLLs). Doing typedefs for function definitions etc. ain't rocket science but it's tedious especially for the twice a year C++ coder like me <s>...
I know I'll be making more use of this...
Other Posts you might also like