Introduction
I’ve got a native console application which would like to interop into a piece of managed code written in C#. This is the how the C# function “Sum” looks like…
My solution explorer looks as follows…
CSharpModule is a CSharp library while TestManagedCall is a native/unmanaged project. My requirement is as follows: call Class1.Sum from TestManagedCall project.
Adding Reference for Interop
To do this we’ll need to first add a reference of CSharpModule to TestManagedCall project. Go to project properties of TestManagedCall project and add a reference to CSharpModule project, see below screenshot…
So the reference of CSharpModule is now added to TestManagedCall project.
Project changes for enabling Interop
Next step is to add a new C++ file to TestManagedCall project. I’ll call the file: CSharpModuleWrapper.cpp, this class will act as a wrapper to our managed library: CSharpModule. This is how my solution will explorer look now…
Right click on CSharpModuleWrapper.cpp in the solution explorer, select properties, and enable CLR for just this one file…
Fixing incompatibilities
Click “Ok”. Now do a full rebuild. You should see following errors pop up, fix them one by one since adding CLR support results in these incompatibilities… (you’ll see these errors popup one by one, so fixing one will lead to another. Keep fixing them and you’ll see the next error).
- cl : Command line error D8016: ‘/ZI’ and ‘/clr’ command-line options are incompatible. Open the file’s(CSharpModuleWrapper.cpp) properties and go to “All Options” under C/C++ node. This is a cool feature to quickly search for an option the properties dialog. Search for /ZI as given in the above error message. CLR compilation doesn’t support /ZI change it to /Zi.
- cl : Command line error D8016: ‘/clr’ and ‘/Gm’ command-line options are incompatible. Again open file’s properties and goto “All Options” under C/C++ node. Search for /Gm as given in the above message… (disable minimal rebuild). Change to /Gm-
- cl : Command line error D8016: ‘/clr’ and ‘/EHs’ command-line options are incompatible. In file’s properties search for /EHs. Switch to /EHa.
- cl : Command line error D8016: ‘/clr’ and ‘/RTC1’ command-line options are incompatible. Change to Default as shown below…
- Disable pre-compiled headers as shown below, search for /Yu under “C/C++->All options”…
With these changes your code will compile. I get following output…
Code Changes for Interop
Now add code to use the CSharpModule’s namespace and add a function to CSharpModuleWrapper class. Eventually this is how my code will look like with all the modifications…
The CSharpModuleWrapper.h has only one change, I added a declaration for Call_Sum().
Don’t forget to call Call_Sum(). This is how the calling code looks like…
Output…
This is a reliable way to make calls into managed world from native world. Of course there are #pragma’s (managed/unmanaged) that you can use but I’m not so confident about using them. This is clean!
Conclusion
The sample I’ve shown is a ‘very’ simple one, I’m sure you’ll have a variety of requirements, let me know if I can help.