How to check .NET accessibility ?
I have a native C++ app.
This app uses LoadLibrary()/GetProcaddress() to optionally load a C++/CLI wrapper dll which calls a .NET 4 class library.
Everything works fine if .NET 4 is installed.
When .NET 4 isn't installed. The LoadLibrary() of the C++/CLI wrapper DLL and and GetProcAddress() of the exported function(s) succeeds. (I would have thought the loadlibrary would fail because the dependant .NET 4 isn't available).
However calling the exported functions causes the application to crash with exception code 0xe0434f4d
What is the proper way to handle this situation ?
- Programmatically check if .NET 4 is installed ? (if so, what is the recommended way to do this ?)
- put a SEH __try/__except around the LoadLibrary/GetProcAddress/ call exported function ?
- somehow check/catch this in the C++/CLI wrapper (if so, how ?)
- somethign else ?
Re: How to check .NET accessibility ?
A mixed-mode DLL like such a wrapper doesn't attempt to load the .NET runtime until the first call to a managed function is made. Insofar LoadLibrary()/GetProcAddress() succeeding in this scenario is the expected behavior.
My initial intuitive preference among the options you list was the SEH approach, probably simply due to the fact that extensively using exceptions becomes sort of a habit when writing quite some .NET code. I questioned whether this would be the best approach, however, due to the overhead of provisions for stack unwinding and lower effectivity of optimizations incurred by that. But as the compiler option /clr not only implies but mandates /EHa (see http://msdn.microsoft.com/en-us/libr...v=vs.100).aspx), there is no way to avoid this overhead anyway, at least in the wrapper DLL. So I'd eventually would recommend the SEH approach.
You can either put the __try/__except construct into the client app executbale or the wrapper DLL, where making it part of the wrapper would IMO improve encapsulation. But, for logical reasons, it's important that this is in a native function, so as part of the wrapper code it either would need to be defined in a separate compiliation unit compiled without /clr or enclosed in appropriate managed/unmanaged pragmas. A native calling convention like WINAPI alone wouldn't make it a native function.
Once the first call to a managed function succeeded, the .NET runtime has been loaded and initialized, and no more exception would get thrown for that reason anymore. So if your wrapper exposes some initialization function or other function that would be called first in any case, it would be sufficient to have the SEH catch there, provided other wrapped functions inside wrapped managed library wouldn't throw any managed exceptions for other reasons (and not catch them themself internally).
I considered an explicit up-front check for .NET runtime availability as well, but didn't find a way to do that except checking whether the required version of the .NET framework is installed as an application (as showing up in the Software category of Control Panel), and didn't really pursue that aproach further, since I think it's quite over-complicated.