浮动*从C到C#
我不是一个真正的CS人,所以如果在座的任何天才能为我指出正确的方向,我将永远感激 我有一个c代码命令行函数,用于将结果写入文件。我将它转换为通过浮点数组返回数据到C++程序(例如避免文件常量I/O): 这很有效。我现在需要把它放到一个C#程序中,这就是事情失控的地方 为了避免字符**,我做的第一件事就是将参数设置为一系列布尔值。如果我允许它仍然转储到文件中,那么效果很好 问题是在c#中处理c样式的浮点数组。在c代码中,它是用malloc分配的 下面是我尝试过但没有成功的所有内容(我知道阵列的大小):浮动*从C到C#,c#,c,pointers,malloc,marshalling,C#,C,Pointers,Malloc,Marshalling,我不是一个真正的CS人,所以如果在座的任何天才能为我指出正确的方向,我将永远感激 我有一个c代码命令行函数,用于将结果写入文件。我将它转换为通过浮点数组返回数据到C++程序(例如避免文件常量I/O): 这很有效。我现在需要把它放到一个C#程序中,这就是事情失控的地方 为了避免字符**,我做的第一件事就是将参数设置为一系列布尔值。如果我允许它仍然转储到文件中,那么效果很好 问题是在c#中处理c样式的浮点数组。在c代码中,它是用malloc分配的 下面是我尝试过但没有成功的所有内容(我知道阵列的大小
我几乎涉猎了我在互联网上能找到的一切。如果需要更多信息,请告诉我。我希望这只是我所缺少的一个简单概念。将此签名用于C函数(用真正的库名替换
mgrib.dll
)
按如下方式调用mgrib
函数:
// Prepare arguments in proper manner
int argc = 0;
StringBuilder[] argv = new StringBuilder[ argc ];
IntPtr pointer = mgrib( argc, argv );
mgrib_free( pointer );
调用完成后,您可以得到如下结果:
float[] result = new float[ size ];
Marshal.Copy( pointer, result, 0, size );
[DllImport( "mgrib.dll", EntryPoint = "mgrib_free",
CallingConvention = CallingConvention.Cdecl )]
public static extern void mgrib_free( IntPtr pointer );
编辑:
由于mgrib
正在使用malloc
分配内存,因此我们需要使用free
函数释放内存。但是,您必须将对free
函数的调用包装到将从本机库导出的另一个函数中
extern "C" __declspec(dllexport) void mgrib_free( float* pointer );
void mgrib_free( float* pointer )
{
free( result );
}
然后像这样将其导入到:
float[] result = new float[ size ];
Marshal.Copy( pointer, result, 0, size );
[DllImport( "mgrib.dll", EntryPoint = "mgrib_free",
CallingConvention = CallingConvention.Cdecl )]
public static extern void mgrib_free( IntPtr pointer );
并按如下方式调用它:
// Prepare arguments in proper manner
int argc = 0;
StringBuilder[] argv = new StringBuilder[ argc ];
IntPtr pointer = mgrib( argc, argv );
mgrib_free( pointer );
忘记C原型,用C#编写一个干净的原型。返回一个浮点数组(float[])。请发布你的c代码。你是想做得好还是容易?简单的方法是让两个程序几乎保持不变,但让程序通过管道而不是文件进行通信。为了做好这项工作,您最好用一种语言编写整个程序。目前,我对c语言非常在行,但c代码太弱,无法将完整(非常大)的程序从c语言转换为c语言。我真希望这是一个选择。我会尝试下面的建议,如果不成功,发布一些c#(这是一个痛苦,因为机器没有连接,所以我需要运动鞋网),虽然这主要是一个循环中的Dllimport调用。其余,非常感谢您的详细回复。这正是我多次尝试中的一次。你的回答给了我信心,让我可以深入一点,一步一步地完成每一次迭代。我发现,在访问“mgrib”256次后,无论发生什么情况,程序都会在没有警告的情况下崩溃。这太巧合了。我用的是Marshal.FreeCoTaskMem。Marshal.FreeHGlobal抛出句柄错误。所以我认为现在很清楚,FreeCoTaskMem并没有完全削减它,不知何故内存没有被释放。有什么想法吗?这是我第一次尝试,但在我学会如何使用IntPtr之前。我试试看。谢谢你回到这里。结果证明,当我返回我感兴趣的数据时,我正在切断c代码中另一个指针的破坏。非常感谢你帮我解决我自己的愚蠢;)!