Our native C++ program is using QuantLib libraries for creating custom implementations for instrument and pricing engine (zero-coupon bond). C++/CLI is then wrapping this native C++ program and exposing only selected methods for its client (C# program). For those completely new to C++/CLI language, there is a relatively comprehensive tutorial available here, written by Adam Sawicki. Needless to say, even this post is presenting relatively simple example of using QuantLib via wrapper, one is able to apply presented scheme to much more complex valuation scenarios. Sounds like a cliche, but "only the sky is the limit" applies well in here.
As far as I see, a programmer is facing complexities here on two fronts : on a pure program level (C++ language, QuantLib library) and on technical level (handling projects and their configurations specifically on Visual Studio). I assume, that the reader is already familiar with C++ language (including its modern features) and has experience on using QuantLib library. Now, in order to decrease the learning curve on that technical level, I decided to include all possible configurations-related steps in here. This means, that when all the steps described in this post have been implemented on a priestly manner, one should end up with succesfully compiled projects. In order to give some concrete back-up for this claim, I have specifically re-created this project succesfully from the scratch now two times.
C++/CLI wrapper project
Create a new C++ CRL Class library project. At this point, pre-installed and pre-built QuantLib and Boost libraries should be available. Create references to required Boost and QuantLib header files and libraries as follows.
In the case one may not have these libraries available, all required procedures for getting this part done correctly is well presented in here and here.
Next, add the following two new header files to this project.
Native C++ header file.
C++/CLI header file.
Next, add the following two implementation files to this project.
Native C++ implementation file.
C++/CLI implementation file.
Next, some C++/CLI project settings needs to be modified.
Disable the use of pre-compiled headers.
Optionally, update properties to suppress (almost) all the other warnings.
After these steps, I have completed a succesfull built for my C++/CLI project.
C# client project
First, create a new C# console project into the existing solution.
Then, add reference to previously created C++/CLI project.
Next, implement the following program to C# project.
Finally, set C# project as start-up project (on Visual Studio, right-click selected C# project and select "Set as StartUp Project").
After completing all previous steps, I have completed a succesfull built for the both projects and got the result of 979953.65 as present value for this 2-year zero-coupon bond, evaluated by using our native C++ QuantLib program via C++/CLI wrapper class.
At this point, we are done.
Postlude : no sweeping under the carpet allowed
Clever eyes might be catching, that there is a SuppressFinalize method call made for Garbage Collector at the end of our C# program. If I will remove that call, I will get the following exception.
Now, the both destructor and finalizer in our C++/CLI project have been correctly implemented, as C++/CLI standard is suggesting. As I understand, the issue is coming from C# program side, as Garbage Collector will do its final memory release sweep before exit. The issue has been pretty completely chewed in here, here and here.
Interesting point is, that in the last given reference above, the author is actually suggesting to delete dynamically allocated member variables (bond and pricer) in destructor. Now, if I will modify that C++/CLI program accordingly as suggested (delete member variables in destructor, not in finalizer, remove trigger call from destructor to finalizer, remove method call for Garbage Collector in C# program), this program will work again as expected. By taking a look at author's past experience, at least I would come to the conclusion, that this suggested approach is also a way to go.
Finally, thanks a lot again for using your precious time for reading this blog. I hope you got what you were looking for.