I have the following structure:
[StructLayout(LayoutKind.Sequential)]
public struct TCurve
{
public int fNumItems; /* Number of TRatePts in fArray */
public IntPtr fArray; /* Dates & rates */ // pointer to an array of TRatePt[]
public long fBaseDate; /* Discount date */
public double fBasis; //ZERO_CURVE_BASIS in capvoll.c which is #defined as ANNUAL_BASIS 1 /* Number compounding periods / year */
public long fDayCountConv; //ZERO_CURVE_DAY_COUNT_CONV in capvoll.c which is #defined as GTO_ACT_365F; = 2L /* How the year fraction is computed */
public IntPtr fClassHandle; /* C++ class handle implementation */
};
[StructLayout(LayoutKind.Sequential)]
public struct TRatePt
{
public long fDate;
public double fRate;
};
The TRatePt is defined as follows:
[DllImport("alib.dll", EntryPoint = "GtoCapFloorAvgVol")]
public static extern int CapFloorAvgVol(
long capStartDate, /* (I) */
long capExpiryDate, /* (I) */
double[] strikeRates, /* (I) */
int numStrikeRates, /* (I) */
double[] principles, /* (I) */
int numPrinciples, /* (I) */
int moneymarketDen, /* (I) # days/year */
ref TDateInterval resetPeriod, /* (I) Time Between caplets */
int optionType, /* (I) Cap or Floor */
char stubPosition, /* (I) 2/16/94 GG 'F'ront or 'B'ack */
[In] IntPtr zeroCurve, /* (I) For discounting Pointer to TCurve*/
double price, /* (I) Price */
double avgVolGuess, /* (I) Average Volatility guess */
out double avgVol); /* (O) Average Volatility */
The C declaration is:
GTO_EXPORT(int ) GtoCapFloorAvgVol(
TDate capStartDate, /* (I) */
TDate capExpiryDate, /* (I) */
double *strikeRates, /* (I) */
int numStrikeRates, /* (I) */
double *principles, /* (I) */
int numPrinciples, /* (I) */
int moneymarketDen, /* (I) # days/year */
TDateInterval *resetPeriod, /* (I) Time Between caplets */
int optionType, /* (I) Cap or Floor */
char stubPosition, /* (I) 2/16/94 GG 'F'ront or 'B'ack */
TCurve *zeroCurve, /* (I) For discounting */
double price, /* (I) Price */
double avgVolGuess, /* (I) Average Volatility guess */
double *avgVol) /* (O) Average Volatility */
Thanks in advance!
Ok so here are the C structs:
typedef struct _TCurve{
int fNumItems; /* Number of TRatePts in fArray */
TRatePt *fArray; /* Dates & rates */
TDate fBaseDate; /* Discount date */
double fBasis; /* Number compounding periods / year */
long fDayCountConv; /* How the year fraction is computed */
void *fClassHandle; /* C++ class handle implementation */ } TCurve;
and :
typedef struct{
TDate fDate;
double fRate;} TRatePt;
By the way if you know how to handle the void* help would be welcome…
PS: TDate is just a
typedef long int TDate;
And here is how I use it:
TCurve _zeroCurve = new TCurve()
{
fBaseDate = _tempValueDate,
fNumItems = _ratePoints.Length,
fBasis = 2L,
fDayCountConv = 1
};
int _sizeOfTCurve = Marshal.SizeOf(typeof(TCurve));
IntPtr p_zeroCurve = Marshal.AllocHGlobal(_sizeOfTCurve);
Marshal.StructureToPtr(_zeroCurve, p_zeroCurve, false);
int _status;
_zeroCurve.fArray = Marshal.AllocHGlobal(_ratePoints.Length * Marshal.SizeOf(typeof(TRatePt)));
try
{
IntPtr _ratePt = _zeroCurve.fArray;
for (int _i = 0; _i < _ratePoints.Length; _i++)
{
Marshal.StructureToPtr(_ratePoints[_i], _ratePt, false);
//_ratePt = new IntPtr(_ratePt.ToInt64() + Marshal.SizeOf(typeof(TRatePt)));
IntPtr _nextRatePt = new IntPtr(_ratePt.ToInt64() + Marshal.SizeOf(typeof(TRatePt)));
_ratePt = _nextRatePt;
//_ratePt += Marshal.SizeOf(typeof(TRatePt));
}
_status = CapFloorAvgVol(_tempStartDate, _temPexpiryDate, strikeRates, strikeRates.Length, principles, principles.Length, moneymarketDen,
ref _resetPeriod, optionType, stubPosition, p_zeroCurve, price, avgVolGuess, out avgVol);
}
finally
{
Marshal.FreeHGlobal(_zeroCurve.fArray);
}
Marshal.FreeHGlobal(p_zeroCurve);
p_zeroCurve = IntPtr.Zero;
OK, here’s how to do what I think you mean, and I’m sorry it took me so long to work it out. You will need to use manual marshalling for the pointer to
TCurve.I’ve simplified your struct for convenience.
I doubt that the
Pack = 1is correct. It’s pretty rare to pack structs in C.Another problem is that
longis 64 bits in C# butlong int,long,intare all 32 bits in C++ on Windows.Finally, the
void*parameter is an opaque pointer and you should declare it asIntPtrin your C# struct.