C ++与C#的DLL互操作:公开未知大小的多维数组,以及内存管理

如何解决C ++与C#的DLL互操作:公开未知大小的多维数组,以及内存管理

| 我有一个C ++库,可以执行一些核心财务数学(Quantlib)。我有一个针对它构建的普通C ++ dll,它向C#前端应用程序公开了一个轻量级接口,以允许用户传递各种参数,运行方案等。然后该dll返回数据以供显示。 我真的不清楚如何处理dll和C#层之间的接口,但是特别是我不知道在哪里处理内存分配/释放,即在C#或dll中 本质上,我希望我的dll返回一个包含二维值数组(double,char *等)的类或结构。我在调用dll时不知道该数组的大小,所以我猜它必须由dll本身分配。 目前,我的dll返回了一个以管道分隔的值列表的looooooooong char *。这似乎可行,但它并不是给我一个特别优雅的解决方案。 大家有帮助吗? 编辑 非常感谢您的所有反馈。抱歉,多年来我都没有进行过任何DLL编程,因此这是一个愚蠢的问题。 我决定将2d数组简单地视为在C ++一侧具有高度/宽度偏移的1d数组,并且只需要猜测数组的大小即可。在C#端创建一个2d数组,并以这种方式将其编组到C ++似乎正常。 这就是我所拥有的。有什么想法吗? C#:
    [DllImport(<dllPath>,CallingConvention = CallingConvention.Cdecl)]
    static extern void ChangeArray2d(double[,] arr,int l1,int l2);

    //populated with some sample values
    double[,] arr = new double[,] { { 1,2,3,4 },{ 5,6,7,8 } };
    ChangeArray2d(arr,arr.GetLength(0),arr.GetLength(1));
C ++:
 __declspec(dllexport) void ChangeArray2d( double* arrayin,int height,int width)
{
    for (int n = 0; n<height; n++){
        for (int m = 0; m<width; m++){
            arrayin[n*width+m]  = arrayin[n*width+m] + 100;
        }
    };
    return;
}
    

解决方法

        通常,分配缓冲区,将其(缓冲区大小作为一次可以处理的最大数据量)传递给C ++本机函数(将填充它,然后处理数据/空闲缓冲区)是一种常见的模式。或重用缓冲区。 如果您的本机函数为您分配了缓冲区,则应在以后释放它-这是易碎的合同,并且还禁止内存重用。例如。如果您需要调用此函数20次-您将有20个不必要的分配。 像这样:
private int YourNativeFunctionStub(IntPtr buffer,int bufferSize)
{
    int writtenToBufferBytes = bufferSize; // if it wrote less to buffer - it should return correct count of bytes
    // here your library fills the buffer with data
    return writtenToBufferBytes;
}

private double[] GetArrayFromNative()
{
    int bufsize = 1024; // probably you should find it by calling another func from your library?

    IntPtr nativeBuffer = Marshal.AllocHGlobal(bufsize);
    try
    {
        int bytesReceivedInBuffer = YourNativeFunctionStub(nativeBuffer,bufsize);

        int receivedArrayLength = bytesReceivedInBuffer / sizeof(double);
        var managedArray = new double[receivedArrayLength];
        Marshal.Copy(nativeBuffer,managedArray,receivedArrayLength);
        return managedArray;
    }
    finally
    {
        Marshal.FreeHGlobal(nativeBuffer);
    }
}
UPD:请参阅Hans的评论。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?