如何调用 C++来自 c# 的函数

发布于 2024-12-14 05:28:17 字数 2088 浏览 0 评论 0原文

我正在尝试用 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# 中使用它),因此欢迎任何其他提示等。

I am trying to call a C++ function provided from a college in C#. He has provided me with a dll and the following header file.

C++ Header

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

I am using the following C# code to call the above c++ function which results in the following error.

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

How do I call this function in C#? Does the C++ code need to change?

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
        }
    }
}           

More background:
My college has develop several financially related calculations and I am hoping with minimal effort we can reuse his entire library in another C# application. Both he an I have very minimal experience in this area (creating exportable C++ code and using it in C#) so any other tips etc will be welcomed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海之角 2024-12-21 05:28:17

您没有机会直接从 C# 调用此函数。 vector<> 与 C# int[] 没有关系。

最好的选择是将 C# 库包装在托管 C++ 包装器中,以便您可以在传入时进行从 C# 类型到 C++ 类型的转换,并在传出时进行从 C++ 类型到 C# 类型的映射。

You've got no chance of calling this function directly from C#. A vector<> has no relation to a C# int[].

Your best bet would be to wrap the C# library in a manged C++ wrapper so that you can do the translation from the C# types to the C++ types on the way in, and the mapping from the C++ types to the C# types on the way out.

一生独一 2024-12-21 05:28:17

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

If you working with the developer of the library (as aposed to just using his lib) it might be worth looking at him providing a C++CLI build that you can work with directly with standard C#. You would need to deal with the vector/stl use in lib code - either replace this with cli Lists (or other managed containers) or find a wrapper solution (There are various SO posts about eg here and here).
I think that is likely going to be easier long term solution than pinvoke based interop to raw C++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文