2011-09-16 37 views
3

這是我的C函數的定義:我可以通過C++/CLI包裝將C#數組傳遞給C指針嗎?

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

第一參數實際上是指向的長的陣列。 在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代碼,我不知道如何聲明在Class 1類功能(我沒有把整個代碼要簡明扼要):

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

我從另一個函數我寫了什麼,我做了第二個參數所知道的是正確的(不知道它的雖然是最好的方法)。但第一個呢?我應該做同樣的事情嗎?即:定義一個指針將它傳遞給C函數,然後將值複製回數組? 問候

+1

您是否需要「固定」陣列/對象? – 2011-09-16 15:23:25

回答

3

正確的解決方案(包括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
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的,這可能是矯枉過正,除非你有更復雜的編組,以做到萬無一失;這可以通過直接從C#使用P/Invoke來更容易地完成:

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

沒有必要的手動封送。

+0

謝謝。但是我用400個函數封裝了一個庫,有些函數返回或接受了複雜的數據結構。我實際上已經開始與PInvoke,但最終,決定放棄它。但我現在實際上正在考慮混合解決方案......您怎麼看? – nche