【问题标题】:How to call a C++ function from c#如何从 C# 调用 C++ 函数
【发布时间】:2011-11-09 08:37:29
【问题描述】:

我正在尝试使用 C# 调用大学提供的 C++ 函数。他为我提供了一个 dll 和以下头文件。

C++ 头文件

#include "../libs/tfvo.h"

extern "C" __declspec(dllexport) vector<double> fvm(
            vector<double> yearFractions,   
            vector<double> discountFactors, 
            vector<double> weightings,      
            double alpha_meanReversion,     
            double sigma_meanReversion,     
            double alpha_shortRate,         
            double alpha_meanReversion,
            double sigma_shortRate,         
            vector<double> startingValues = vector<double>(3,0.01));

我正在使用以下 C# 代码调用上述 c++ 函数,导致以下错误。

“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”

如何在 C# 中调用此函数? C++代码需要改吗?

C#

var result = SimpleDllTest.testWrapper(); // In a console app

class SimpleDllTest
{
    [DllImport("fvm.dll")]
    public static extern IntPtr fitVasicekModel(
        IntPtr yearFractions,
        IntPtr weightings,
        double alpha_meanReversion,     
        double sigma_meanReversion,     
        double alpha_shortRate,         
        double sigma_shortRate,
        IntPtr startingValues
        );


    public static double [] testWrapper()
    {

        var t = new double[] { 0.1, 1.2 };
        var v = new double[] { 0.1, 1.2 };

        int size = Marshal.SizeOf(t[0]) * t.Length;
        IntPtr pnt = Marshal.AllocHGlobal(size);
        Marshal.Copy(t, 0, pnt, t.Length);

        int sizev = Marshal.SizeOf(v[0]) * v.Length;
        IntPtr pntv = Marshal.AllocHGlobal(sizev);
        Marshal.Copy(v, 0, pntv, v.Length);

        IntPtr result = fitVasicekModel(pnt, pnt, 1, 1, 1, 1, pntv);
        try
        {
            return (double[])Marshal.PtrToStructure(result , typeof(double[]));
        }
        finally
        {
            // Free the pointer here if it's allocated memory
        }
    }
}           

更多背景: 我的大学已经开发了几个与财务相关的计算,我希望我们能以最小的努力在另一个 C# 应用程序中重用他的整个库。他和我在这方面的经验都非常少(创建可导出的 C++ 代码并在 C# 中使用它),因此欢迎任何其他提示等。

【问题讨论】:

  • 再次查看提供的签名和 pinvoke 导入。并不是说这是[唯一]问题,但它不匹配。
  • 你们大学可以用C++CLI编译他的代码吗?
  • @Ricibob - 不确定,但这是一个选项。将调查
  • @pst - 请您也强调其他问题。当您说签名不匹配时,我是否应该将 C# 方法 sig 更改为使用double[]

标签: c# pinvoke


【解决方案1】:

您没有机会直接从 C# 调用此函数。 vector&lt;&gt; 与 C# int[] 无关。

最好的办法是将 C# 库包装在一个托管的 C++ 包装器中,这样您就可以在进入的过程中进行从 C# 类型到 C++ 类型的转换,以及从 C++ 类型到 C# 类型的映射出路。

【讨论】:

    【解决方案2】:

    如果您与库的开发人员一起工作(建议只使用他的库),那么可能值得看看他提供的 C++CLI 构建,您可以直接使用标准 C#。您需要处理 lib 代码中的 vector/stl 使用 - 要么用 cli 列表(或其他托管容器)替换它,要么找到一个包装解决方案(有各种 SO 帖子,例如 herehere)。 我认为这可能是比基于 pinvoke 的原始 C++ 互操作更容易的长期解决方案。

    【讨论】:

      猜你喜欢
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多