float *从C到C#

时间:2011-03-08 18:27:52

标签: c# c pointers malloc marshalling

我不是真正的CS家伙,所以如果你们这里的任何天才能指出我正确的方向,我将永远感激。

我有一个c-code命令行函数,用于将其结果写入文件。我将它转换为通过float *数组将其数据返回到类似的C ++程序(以避免常量文件I / O):

float * mgrib(int argc, char **argv)

这完美无缺。我现在需要把它变成一个C#程序,这就是事情变得混乱的地方。

我做的第一件事就是避免使用char **来使争论成为一系列bool。如果我允许它仍然转储到文件,这工作正常。

问题是在C#中使用c样式的float数组。在c-code中,它被分配了malloc。

所以这是我尝试过的一切都没有成功(我知道数组的大小):

  1. 制作一个“免费”功能,以便在完成后从C#调用以释放内存。经过几次循环后,C#崩溃,没有任何警告。

  2. 使用Marshal.FreeCoTaskMem从C#释放malloc。同样的结果。

  3. 将float *移动到参数并删除c-code malloc。 (void mgrib(...,float * data,...)

  4. __ a)用Marshal.AllocCoTaskMem分配它。使用Marshal.FreeCoTaskMem释放它。

    __ b)使用Marshal.Copy进行分配。使用Marshal.FreeCoTaskMem释放它(也许这是错的?)

    我已经涉足了我能在互联网上找到的所有东西。如果需要更多信息,请告诉我。我希望这只是一个我想念的简单概念。

1 个答案:

答案 0 :(得分:5)

将此签名用于C函数(将mgrib.dll替换为真实的库名称。)

[DllImport( "mgrib.dll", EntryPoint = "mgrib" )]
public static extern IntPtr mgrib(
    int argc,
    [MarshalAs( UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr )]
    StringBuilder[] argv );

按如下方式调用mgrib函数:

// Prepare arguments in proper manner
int argc = 0;
StringBuilder[] argv = new StringBuilder[ argc ];
IntPtr pointer = mgrib( argc, argv );

调用完成后,您可以得到如下结果:

float[] result = new float[ size ];
Marshal.Copy( pointer, result, 0, size );

修改

由于mgrib使用malloc分配内存,我们需要使用free函数释放内存。但是,您必须在另一个将从本机库导出的函数中包含对free函数的调用。

extern "C" __declspec(dllexport) void mgrib_free( float* pointer );

void mgrib_free( float* pointer )
{
    free( result );
}

然后将其导入如下:

[DllImport( "mgrib.dll", EntryPoint = "mgrib_free",
            CallingConvention = CallingConvention.Cdecl )]
public static extern void mgrib_free( IntPtr pointer );

并按如下方式调用它:

mgrib_free( pointer );