2011-09-16 85 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

相关问题