3

Here is my C function definition:

//C
int FXForwardRate(
    long         *riskZCDates,      /* (I) Risk ZC dates */ 
    double       *fwdRate);         /*(O) Output */

the first parameter is actually pointing to an array of long. In C# I would ideally like to call it like this:

//C#    
int[] array = {1,2,3}; //if i'm not mistaking long in C is int in :NET
double fwdRate = 0;

Class1.FXForwardRate(array, ref fwdRate);

Now for my C++/CLI code I don't know how to declare the function in a Class1 class (I didn't put the whole code to be concise):

//C++/CLI
int Class1::FXForwardRateW(int[] premium, double %fwdRate)
{
     double _tempFwdRate = 0.0;
     int _status = FXForwardRate(premium, &_tempFwdRate);
     fwdRate = _tempFwdRate;
     return _status;
}

I know from another function I wrote that what I did for the second parameter is right (not sure it's the best method though). But how about the first one? Should I do the same thing? ie: define a pointer pass it to the C function and then copy the values back to the array? Regards

1
  • 1
    Do you have to "pin" the array/object? Commented Sep 16, 2011 at 15:23

2 Answers 2

3

The correct solution (both Lirik and pst gave pointers in the right direction) would be:

int Class1::FXForwardRateW(array<int>^ premium, double %fwdRate)
{
     double tempFwdRate = fwdRate;
     pin_ptr<int> premiumPtr = &premium[0];
     int status = FXForwardRate(premiumPtr, &tempFwdRate);
     fwdRate = tempFwdRate;
     return status;
}
Sign up to request clarification or add additional context in comments.

Comments

0
using System::Runtime::InteropServices::OutAttribute;

int Class1::FXForwardRateW(array<int>^ premium, [Out] double% fwdRate)
{
    double tempFwdRate;
    pin_ptr<int> pin = &premium[0];
    int status = FXForwardRate(reinterpret_cast<long*>(pin), &tempFwdRate);
    fwdRate = tempFwdRate;
    return status;
}

This will appear to C# to have the signature:

int FXForwardRateW(int[] premium, out double fwdRate);

(If fwdRate is truly output-only and not input/output then semantically you want the argument type to be out double rather than ref double.)


However, note that using C++/CLI for this may be overkill unless you have more complicated marshaling to do elsewhere; this could be done more easily using P/Invoke directly from C#:

[DllImport("c-library-name.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int FXForwardRate(int[] premium, out double fwdRate);

No manual marshaling necessary.

1 Comment

Thanks. But I'm wrapping a library with 400 functions and some have return or take in complex Data Structures. I had actually set out with PInvoke but in the end, decided to drop it. But I'm actually thinking about a mixed solution now... What do you think?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.