Posted by
Ken Goodhew on
URL: http://quantlib.414.s1.nabble.com/Managed-C-and-Quantlib-tp4126p4128.html
Alexander,
My company did exactly what you are proposing. We have a rather large
C#/VB.Net application (managed code) that links to a Quantlib library
(unmanaged code). We use the option evaluation software for real time
analytics.
In short, it was a real pain due to the strange rules Microsoft has for
mixing managed and unmanaged code. However it was much less work than
writing all the engines from scratch.
We created two new projects. The first I call QuantlibWrapper, which
implements step (b) described below. The second, I call
CSharpTestDriver, which makes calls to the QuantlibWrapper code to prove
it works. The output of QuantlibWrapper is a dll, which any managed
.Net project can access.
I had to fool around a bit with the C/C++ flags and the Linker flags to
get QuantlibWrapper to compile. My notes are a little sketchy, but here
they are:
C/C++
General - Add include dir ..
Preprocessor - NOMINMAX
Language - /GR (enable run-time type info)
Linker
Add include ..\lib
Output file ..\lib\QuantlibWrapper-VC71-gd-0_3_9.dll
Command Line - Remove \noentry
Input - remove nochkclr.obj (it generates warnings)
I've attached the files I used to wrap the Day counters as an example.
I hope this pattern will help you implement it for other classes.
Good luck.
Ken Goodhew
Aspen Research Group, LTD.
Alexander Ng wrote:
> Hi all,
>
> Does anyone have any experience using Quantlib from a .NET environment
> using managed C++?
>
> I have a Microsoft Visual Studio .NET 2003 setup with Managed C++,
> standard C++, C# installed.
>
> Quantlib was successfully compiled on my setup.
>
> According to the Microsoft C++ migration guidelines, it should be
> possible to:
>
> (a) compile Quantlib as standard C++ libraries using the C++ compiler
> in VS .NET 2003.
> (b) write a Managed C++ wrapper library containing managed C++ classes
> which are thin wrappers to underlying Quantlib class methods.
> (c) Invoke the Managed C++ classes from other .NET languages in
> particular C#.
>
> I am not trying to port the entire Quantlib functionality into a
> managed C++ framework, but would start with basic functionality such
> as basic matrix calculation, simple math functions.
>
> Any suggestions about which Quantlib class to wrap as managed C++ and
> invoke to do something basic like inverting a N by N matrix.
>
> Also, the Quantlib website mentions failed attempts to port the
> library to .NET. Did they use my proposed approach?
>
> Many thanks. Alexander Ng
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads, discussions,
> and more.
http://solutions.newsforge.com/ibmarch.tmpl> _______________________________________________
> Quantlib-users mailing list
>
[hidden email]
>
https://lists.sourceforge.net/lists/listinfo/quantlib-users>
#include "stdafx.h"
#include <iostream>
#include "QLDayCounter.hpp"
//------------------------------ Unmanaged Code --------------------
#pragma unmanaged
namespace UnmanagedQLWrapper
{
QLDayCounterUM::QLDayCounterUM(void)
{
}
QLDayCounterUM *QLDayCounterUM::Actual360Factory()
{
QLDayCounterUM *ret = new QLDayCounterUM();
ret->counter_ = new Actual360();
return ret;
}
QLDayCounterUM *QLDayCounterUM::Actual365FixedFactory()
{
QLDayCounterUM *ret = new QLDayCounterUM();
ret->counter_ = new Actual365Fixed();
return ret;
}
QLDayCounterUM *QLDayCounterUM::ActualActualFactory()
{
QLDayCounterUM *ret = new QLDayCounterUM();
ret->counter_ = new ActualActual();
return ret;
}
QLDayCounterUM *QLDayCounterUM::SimpleFactory()
{
QLDayCounterUM *ret = new QLDayCounterUM();
ret->counter_ = new SimpleDayCounter();
return ret;
}
QLDayCounterUM *QLDayCounterUM::Thirty360Factory()
{
QLDayCounterUM *ret = new QLDayCounterUM();
ret->counter_ = new Thirty360();
return ret;
}
}
//----------------------- Managed Code -----------------------
#pragma managed
namespace QLWrapper
{
QLDayCounter &QLDayCounter::Actual360Factory()
{
QLDayCounter *ret = new QLDayCounter();
ret->counterUM_ = UnmanagedQLWrapper::QLDayCounterUM::Actual360Factory();
return *ret;
}
QLDayCounter &QLDayCounter::Actual365FixedFactory()
{
QLDayCounter *ret = new QLDayCounter();
ret->counterUM_ = UnmanagedQLWrapper::QLDayCounterUM::Actual365FixedFactory();
return *ret;
}
QLDayCounter &QLDayCounter::ActualActualFactory()
{
QLDayCounter *ret = new QLDayCounter();
ret->counterUM_ = UnmanagedQLWrapper::QLDayCounterUM::ActualActualFactory();
return *ret;
}
QLDayCounter &QLDayCounter::SimpleFactory()
{
QLDayCounter *ret = new QLDayCounter();
ret->counterUM_ = UnmanagedQLWrapper::QLDayCounterUM::SimpleFactory();
return *ret;
}
QLDayCounter &QLDayCounter::Thirty360Factory()
{
QLDayCounter *ret = new QLDayCounter();
ret->counterUM_ = UnmanagedQLWrapper::QLDayCounterUM::Thirty360Factory();
return *ret;
}
}
// QLDayCounter.hpp
// This is managed code
#pragma once
#include <ql/quantlib.hpp>
using namespace System;
using namespace QuantLib;
//------------------------------ Unmanaged Code --------------------
#pragma unmanaged
namespace UnmanagedQLWrapper
{
class QLDayCounterUM
{
public:
QLDayCounterUM(void);
inline ~QLDayCounterUM(void) { delete(counter_); }
static QLDayCounterUM *Actual360Factory();
static QLDayCounterUM *Actual365FixedFactory();
static QLDayCounterUM *ActualActualFactory();
static QLDayCounterUM *SimpleFactory();
static QLDayCounterUM *Thirty360Factory();
inline DayCounter* MyDayCounter() { return counter_; }
private:
DayCounter* counter_;
};
}
//----------------------- Managed Code -----------------------
#pragma managed
namespace QLWrapper
{
public __gc class QLDayCounter
{
public:
inline ~QLDayCounter(void) { delete(counterUM_); }
static QLDayCounter &Actual360Factory();
static QLDayCounter &Actual365FixedFactory();
static QLDayCounter &ActualActualFactory();
static QLDayCounter &SimpleFactory();
static QLDayCounter &Thirty360Factory();
public private:
UnmanagedQLWrapper::QLDayCounterUM* counterUM_;
private:
inline QLDayCounter(void) {}
};
}