【问题标题】:Can I pass a C# array to a C pointer via a C++/CLI wrapper?我可以通过 C++/CLI 包装器将 C# 数组传递给 C 指针吗?
【发布时间】:2011-09-16 15:13:10
【问题描述】:

这是我的 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函数,然后将值复制回数组? 问候

【问题讨论】:

  • 你必须“固定”数组/对象吗?

标签: c# c arrays c++-cli wrapper


【解决方案1】:

正确的解决方案(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;
}

【讨论】:

    【解决方案2】:
    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);
    

    无需手动编组。

    【讨论】:

    • 谢谢。但我正在包装一个包含 400 个函数的库,其中一些函数返回或接收复杂的数据结构。我实际上已经开始使用 PInvoke,但最终决定放弃它。但我现在实际上正在考虑一个混合解决方案......你怎么看?
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2018-04-08
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多