Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
emxArray_real_T到C#结构加上初始化_C#_Matlab_Pinvoke_Matlab Coder - Fatal编程技术网

emxArray_real_T到C#结构加上初始化

emxArray_real_T到C#结构加上初始化,c#,matlab,pinvoke,matlab-coder,C#,Matlab,Pinvoke,Matlab Coder,我正在尝试为此C#结构创建一个“构造函数”(包括初始尝试): C对应的C结构如下所示: typedef struct emxArray_real_T { real_T *data; int32_T *size; int32_T allocated; int32_T numDimensions; boolean_T canFreeData; } emxArray_real_T; 并进行了解释 期待任何意见/答复。谢谢 关于如何做到这一点,您有两种选择。您可以分配非托

我正在尝试为此C#结构创建一个“构造函数”(包括初始尝试):

C对应的C结构如下所示:

typedef struct emxArray_real_T
{
   real_T *data;
   int32_T *size;
   int32_T allocated;
   int32_T numDimensions;
   boolean_T canFreeData;
} emxArray_real_T;
并进行了解释


期待任何意见/答复。谢谢

关于如何做到这一点,您有两种选择。您可以分配非托管内存。然后将托管内存中的内容复制到其他内存中。然后,当您对本机代码的调用返回时,可能会将其复制回去

既然您的示例将
canFreeData
设置为
false
,那么我想您应该用另一种方式来做。这就是将托管内存向下传递给本机代码。为了做到这一点,您需要固定它以防止GC移动

为了使这两种方法都有效,我认为您需要一个包装器类来管理本机内存或固定。下面是我如何处理固定方法的:

[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();
    }
}
代码:

声明:

[DllImport("TestFunc.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestFunc(int n, double WnLow, double WnHigh, ref emxArray_real_T kernel);
使用它:

public double[] CalculateBandPassCoefficients(int order, double FreqCutoffNormLow, double FreqCutoffNormHigh)
{
    double[] kernel = new double[order];
    using (emxArray_real_T_Wrapper wb = new emxArray_real_T_Wrapper(kernel))
    {
        TestFunc(order, FreqCutoffNormLow, FreqCutoffNormHigh, ref kernelWrapper.Value);

        kernel = kernelWrapper.Data;
    }
    return kernel;
}

注释。在这段代码中,sizeHandle是int[2],它表示一个2d数组,但不与numDimensions=1对齐。此外,还应澄清该答案如何比公认答案提供改进。
[DllImport("TestFunc.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestFunc(int n, double WnLow, double WnHigh, ref emxArray_real_T kernel);
public double[] CalculateBandPassCoefficients(int order, double FreqCutoffNormLow, double FreqCutoffNormHigh)
{
    double[] kernel = new double[order];
    using (emxArray_real_T_Wrapper wb = new emxArray_real_T_Wrapper(kernel))
    {
        TestFunc(order, FreqCutoffNormLow, FreqCutoffNormHigh, ref kernelWrapper.Value);

        kernel = kernelWrapper.Data;
    }
    return kernel;
}