IJW (It Just Works) - Does it really?
I am in the middle of a task to write a bridge component between the managed components and application written in C#, and the Algorithms DLL's written in (Unmanaged C++). Since performance is very important, I opted for the IJW option.
According to the literature, this should be very simple, after all “It Just Works”.
However, this turns out to be not simple at all.
First of all, I had to recompile the Algorithm DLL's with Visual Studio .NET 2003.
Since the C++ compiler is more ANSI-standard, the code didn't compile and link without changes. Some of these changes were:
1. ifstream has changed and ios::nocreate is deprecated. So I had to use a hack, opening the file in read mode and then closing it and reopening in write mode.
2. Objects that are const, and are passed into a method by reference had to be casted to the non-const object (e.g. const Model to (Model&)).
3. When a function is overloaded, explicit casting was required.
for example (compile error: )
error C2668: 'floor' : ambiguous call to overloaded function
d:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\math.h(604): could be 'long double floor(long double)'
d:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\math.h(556): or 'float floor(float)'
d:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\math.h(209): or 'double floor(double)'
while trying to match the argument list '(int)'
I'm not saying these thing are bad, they are very good to be forced on new code, however it means that code can't be used so easily without changes, and it is sometimes difficult to change old legacy code without breaking changes. (No the code does not have unit tests).
After getting the code to compile (without the CLR flag) in the unmanaged form, I wanted to compile it with in the managed form and to created a managed wrapper for the interface I wanted to create.
After some more IDE wrestling, I got the $$^$@^(@!# Dll to compile and link and was able to reference it from my C# project.
However, I started getting link warnings such as: '.CRT section exists; there may be unhandled static initializes or teminators'
and runtime errors such as: Assertion Failed! (_CrtIsValidHeapPointer(pUserData)).
It turns out that there is a possible bug when using mixed dll's: (quoting from Microsoft document) Applications using mixed DLL's, a combination of both native and Microsoft Intermediate Language (MSIL) DLLs, created with the Visual C++® .NET and Visual C++ .NET 2003 compiler can encounter deadlock scenarios under some circumstances while being loaded. (links at the end)
Applications using mixed DLL's, a combination of both native and Microsoft Intermediate Language (MSIL) DLLs, created with the Visual C++® .NET and Visual C++ .NET 2003 compiler can encounter deadlock scenarios under some circumstances while being loaded.
It looks like I will have to dive into the C++ code (“So you thought you left me behind, huh? You can't get rid of me so fast. Ha, ha ha“ said the C++ devil in my mind). At least I get to learn how to use C++ with Managed Extensions.
Conclusion: IJW is a marketing term. Things don't just work so easily. While you can probably use unmanaged code from managed code, it's not as easy as it may seem.
Mixed DLL Loading Problem
How Can You Migrate your Existing Applications?
Article about Porting of Quake II game - mentions problems above.