Могу ли я передать массив C # указателю C через оболочку C ++ / CLI? - PullRequest
3 голосов
/ 16 сентября 2011

Вот мое определение функции C:

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

первый параметр фактически указывает на массив long.В C # в идеале я хотел бы назвать это так:

//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);

Теперь для своего кода C ++ / CLI я не знаю, как объявить функцию в классе Class1 (я не поставил веськод должен быть кратким):

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

Я знаю из другой функции, которую я написал, что то, что я сделал для второго параметра, является правильным (хотя я не уверен, что это лучший метод).Но как насчет первого?Должен ли я сделать то же самое?то есть: определить указатель передать его в функцию C, а затем скопировать значения обратно в массив?Привет

Ответы [ 2 ]

3 голосов
/ 16 сентября 2011

Правильное решение (и Lirik, и pst указали в правильном направлении):

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;
}
0 голосов
/ 16 сентября 2011
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;
}

Это будет выглядеть в C # с подписью:

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

(Если fwdRate действительно только для вывода, а не для ввода / вывода, то семантически вы хотите, чтобы тип аргумента был out double, а не ref double.)


Тем не менее, обратите внимание, что использование C ++ / CLI для этого может быть излишним, если у вас нет более сложного маршалинга, чтобы сделать его в другом месте;это можно сделать проще, используя P / Invoke непосредственно из C #:

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

Ручное маршалинг не требуется.

...