Ant*_*ony 7 c c# malloc pointers marshalling
我不是真正的CS家伙,所以如果你们这里的任何天才能指出我正确的方向,我将永远感激.
我有一个c-code命令行函数,用于将其结果写入文件.我将它转换为通过float*数组将其数据返回到类似的C++程序(以避免常量文件I/O):
float * mgrib(int argc, char **argv)
Run Code Online (Sandbox Code Playgroud)
这非常有效.我现在需要把它变成一个C#程序,这就是事情变得混乱的地方.
我做的第一件事就是避免使用char**来使争论成为一系列的bool.如果我允许它仍然转储到文件,这工作正常.
问题是在C#中使用c风格的float数组.在c-code中,它被分配了malloc.
所以这是我尝试过的一切都没有成功(我知道数组的大小):
制作一个"免费"函数导出到C#调用,以便在完成后释放内存.经过几次循环后,C#崩溃,没有任何警告.
使用Marshal.FreeCoTaskMem从C#释放malloc.结果相同.
将float*移动到参数并删除c代码malloc.(void mgrib(...,float*data,...)
__a)使用Marshal.AllocCoTaskMem分配它.使用Marshal.FreeCoTaskMem释放它.
__b)使用Marshal.Copy进行分配.使用Marshal.FreeCoTaskMem释放它(也许这是错的?)
我已经涉足了我能在网上找到的所有东西.如果需要更多信息,请告诉我.我希望这只是一个我想念的简单概念.
将此签名用于C函数(替换为mgrib.dll
真实库名称).
[DllImport( "mgrib.dll", EntryPoint = "mgrib" )]
public static extern IntPtr mgrib(
int argc,
[MarshalAs( UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr )]
StringBuilder[] argv );
Run Code Online (Sandbox Code Playgroud)
调用mgrib
函数如下:
// Prepare arguments in proper manner
int argc = 0;
StringBuilder[] argv = new StringBuilder[ argc ];
IntPtr pointer = mgrib( argc, argv );
Run Code Online (Sandbox Code Playgroud)
调用完成后,您可以得到如下结果:
float[] result = new float[ size ];
Marshal.Copy( pointer, result, 0, size );
Run Code Online (Sandbox Code Playgroud)
编辑:
由于mgrib
是使用分配内存malloc
,我们需要使用free
函数释放内存.但是,您必须将调用free
函数包装在另一个将从本机库导出的函数中.
extern "C" __declspec(dllexport) void mgrib_free( float* pointer );
void mgrib_free( float* pointer )
{
free( result );
}
Run Code Online (Sandbox Code Playgroud)
然后将其导入如下:
[DllImport( "mgrib.dll", EntryPoint = "mgrib_free",
CallingConvention = CallingConvention.Cdecl )]
public static extern void mgrib_free( IntPtr pointer );
Run Code Online (Sandbox Code Playgroud)
并按如下方式调用它:
mgrib_free( pointer );
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4346 次 |
最近记录: |