emxArray_real_T到C#结构加初始化 [英] emxArray_real_T to C# struct plus initialisation

查看:946
本文介绍了emxArray_real_T到C#结构加初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建此C#结构一个构造(包括最初的尝试):

I am trying to create a 'constructor' for this C# struct (initial attempt included):

[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
{
public IntPtr data;
public IntPtr size;
public int allocatedSize;
public int numDimensions;
[MarshalAs(UnmanagedType.U1)]
public bool canFreeData;

public emxArray_real_T(double[] cSharpData)
{
    var arraySize = Marshal.SizeOf(cSharpData[0]) * cSharpData.Length;
    this.data = Marshal.AllocHGlobal(arraySize);
    // ????
    numDimensions = 1;
    canFreeData = false;
}
}



相应的C结构的C看起来是这样的:

The C corresponding C struct looks like this:

typedef struct emxArray_real_T
{
   real_T *data;
   int32_T *size;
   int32_T allocated;
   int32_T numDimensions;
   boolean_T canFreeData;
} emxArray_real_T;

和解释的这里

期待任何意见/答案。谢谢!

Looking forward to any comments/answers. Thanks!

推荐答案

您有几个选择,至于如何做到这一点。您可以分配非托管内存。然后将您的托管内存跨越的内容。然后,想必它复制回来时,你的电话到本机代码的回报。

You have a couple of choices as to how to do this. You can allocate unmanaged memory. And then copy the contents of your managed memory across. And then presumably copy it back when your call into native code returns.

由于您的示例设置 canFreeData 那么我想你想要做它的其他方式。那就是通过管理存储器下降到本地代码。为了做到这一点,你需要用别针把它保护它从GC运动。

Since your example sets canFreeData to false then I guess you want to do it the other way. And that is to pass the managed memory down to the native code. In order to do that you need to pin it to protect it from GC movement.

为了使这两种方法的工作,我想你需要一个包装类来管理任一本机存储器,或钉扎。以下是我最好的解决办法钉:

In order to make either of these approaches work I think you need a wrapper class to managed either the native memory, or the pinning. Here's how I'd tackle the pinning approach:

[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
{
    public IntPtr data;
    public IntPtr size;
    public int allocatedSize;
    public int numDimensions;
    [MarshalAs(UnmanagedType.U1)]
    public bool canFreeData;
}

public class emxArray_real_T_Wrapper : IDisposable
{
    private emxArray_real_T value;
    private GCHandle dataHandle;
    private GCHandle sizeHandle;

    public emxArray_real_T Value {
        get { return value; } 
    }

    public emxArray_real_T_Wrapper(double[] data)
    {
        dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
        value.data = dataHandle.AddrOfPinnedObject();
        sizeHandle = GCHandle.Alloc(new int[] { data.Length }, GCHandleType.Pinned);
        value.size = sizeHandle.AddrOfPinnedObject();
        value.allocatedSize = data.Length;
        value.numDimensions = 1;
        value.canFreeData = false;
    }

    public void Dispose()
    {
        dataHandle.Free();
        sizeHandle.Free();
        GC.SuppressFinalize(this);
    }

    ~emxArray_real_T_Wrapper()
    {
        Dispose();
    }
}

这篇关于emxArray_real_T到C#结构加初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆