从C浮动到C# [英] float* from C to C#

查看:88
本文介绍了从C浮动到C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不是一个真正的CS专家,所以如果你们中的任何天才都能指出我正确的方向,我将永远感激不已.

I'm not truly a CS guy, so if any of you geniuses on here can point me in the right direction I'll be eternally grateful.

我有一个C代码命令行函数,用于将其结果写入文件.我将其转换为通过float *数组将其数据返回到像这样的C ++程序中(以避免恒定的文件I/O):

I have a c-code command line function that used to write its results to file. I converted it to return it's data via a float* array to a C++ program like such (to avoid constant file I/O):

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

这很好用.现在,我需要将其放入C#程序中,这就是麻烦的地方.

This worked perfectly. I now need to get this into a C# program, and here's where things go haywire.

我要避免使用char **的第一件事是使参数成为一系列布尔值.如果我允许它仍然转储到文件,那很好.

The first thing I did to avoid the char ** was to make the arguments a series of bool. That worked fine if I allow it to still dump to file.

问题在于在C#中使用c样式的float数组.在C代码中,它是使用malloc分配的.

The problem is juggling the c-style float array in C#. Within the c-code it was allocated with malloc.

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

So here's everything I've tried with no success(I know the size of the array):

  1. 制作完一个免费"函数以从C#导出以释放内存.几次循环后,C#崩溃,没有任何警告.

  1. Make a "free" function to export to call from C# to release the memory when I'm done with it. After a few loops the C# crashes with no warning.

使用Marshal.FreeCoTaskMem从C#释放malloc.结果相同.

Release the malloc from C# with Marshal.FreeCoTaskMem. Same result.

将float *移至参数并删除c代码malloc. (避免使用mgrib(...,float * data,...)

Move the float* to an argument and remove the c-code malloc. (void mgrib(..., float* data,...)

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

__a)Allocate it with Marshal.AllocCoTaskMem. Free it with Marshal.FreeCoTaskMem.

__ b)使用元帅复制进行分配.使用Marshal.FreeCoTaskMem释放它(也许这是错误的吗?)

__b)Use Marshal.Copy to allocate. Free it with Marshal.FreeCoTaskMem (Maybe this is wrong?)

我已经涉足了几乎所有可以在互联网上找到的东西.请让我知道是否需要更多信息.我希望这只是我所缺少的一个简单概念.

I've dabbled in just about everything I could find in the internet. Please let me know if more info is necessary. I'm hoping this just a simple concept that I'm missing.

推荐答案

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

Use this signature for your C function (replace the mgrib.dll with real library name).

[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 );

通话结束后,您可以得到如下结果:

When the call is done, you can get the result like this:

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

编辑:

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

Since the mgrib is allocating the memory using malloc, we need to free the memory using free function. However, you will have to wrap the call to free function in another function that will be exported from native library.

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 );

这篇关于从C浮动到C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆