2011-03-08 86 views
6

我不是一个真正的CS人,所以如果你们中的任何一位天才都能指引我走向正确的方向,我会永远感激。float * from C to C#

我有一个c代码命令行函数,用于将其结果写入文件。我将它转换到经由浮子*阵列返回它的数据到像这样(以避免恒定文件I/O)C++程序:

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

这完美地工作。我现在需要把它变成一个C#程序,这里是事情发生的地方。

我为避免char **所做的第一件事是将参数设置为一系列布尔值。如果我允许它仍然转储到文件,那工作正常。

问题是在C#中杂耍C风格的浮动数组。在c代码中,它被分配了malloc。

因此,这里的一切,我没有成功尝试(我知道数组的大小):

  1. 做一个“免费”的功能,以出口从C#打电话的时候我来释放内存米做完了。几次循环后,C#崩溃,没有任何警告。

  2. 从Marshal.FreeCoTaskMem的C#发布malloc。同样的结果。

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

__a)将其与Marshal.AllocCoTaskMem一起分配。用Marshal.FreeCoTaskMem免费。

__b)使用Marshal.Copy分配。免费与Marshal.FreeCoTaskMem它(也许这是错的?)

我已经涉足了我可以在互联网上找到的一切。如果需要更多信息,请让我知道。我希望这只是一个简单的概念,我错过了。

+5

忘了C语言,写一个干净的用C#。而是返回一个浮点数组(float [])。 – stefan 2011-03-08 18:30:41

+1

请发布您的C#代码 – 2011-03-08 18:39:09

+2

您是否试图做到这一点,或容易吗?简单的方法是将两个程序几乎保持完好,但通过管道而不是文件进行通信。要做得好,你最好用一种语言编写整个程序。 – 2011-03-08 19:12:29

回答

4

将此签名用于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); 
+0

休息,非常感谢您的详细回复。这实际上正是我为我的许多尝试之一所做的。你的回答让我有信心深入一点,逐步完成每一次迭代(唉)。我发现无论程序访问256次mgrib后程序崩溃都没有警告。这有点太巧合了。我正在使用Marshal.FreeCoTaskMem。 Marshal.FreeHGlobal抛出一个句柄错误。所以我认为现在FreeCoTaskMem并没有完全削减它,但内存不会被释放。任何想法的人? – Anthony 2011-03-09 02:13:10

+0

@Anthony:新信息有帮助吗? – 2011-03-09 21:08:08

+0

这是我尝试的第一件事,但在我学会了如何使用IntPtr之前。我会试一试。感谢您回到这里。 – Anthony 2011-03-10 20:33:25