Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
浮动*从C到C#_C#_C_Pointers_Malloc_Marshalling - Fatal编程技术网

浮动*从C到C#

浮动*从C到C#,c#,c,pointers,malloc,marshalling,C#,C,Pointers,Malloc,Marshalling,我不是一个真正的CS人,所以如果在座的任何天才能为我指出正确的方向,我将永远感激 我有一个c代码命令行函数,用于将结果写入文件。我将它转换为通过浮点数组返回数据到C++程序(例如避免文件常量I/O): 这很有效。我现在需要把它放到一个C#程序中,这就是事情失控的地方 为了避免字符**,我做的第一件事就是将参数设置为一系列布尔值。如果我允许它仍然转储到文件中,那么效果很好 问题是在c#中处理c样式的浮点数组。在c代码中,它是用malloc分配的 下面是我尝试过但没有成功的所有内容(我知道阵列的大小

我不是一个真正的CS人,所以如果在座的任何天才能为我指出正确的方向,我将永远感激

我有一个c代码命令行函数,用于将结果写入文件。我将它转换为通过浮点数组返回数据到C++程序(例如避免文件常量I/O):

这很有效。我现在需要把它放到一个C#程序中,这就是事情失控的地方

为了避免字符**,我做的第一件事就是将参数设置为一系列布尔值。如果我允许它仍然转储到文件中,那么效果很好

问题是在c#中处理c样式的浮点数组。在c代码中,它是用malloc分配的

下面是我尝试过但没有成功的所有内容(我知道阵列的大小):

  • 制作一个“free”函数,从C#导出调用,以便在完成后释放内存。循环几圈后,C#在没有任何警告的情况下崩溃

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

  • 将浮点*移动到参数并删除c代码malloc。(无效mgrib(…,浮点*数据…)

  • __a) 使用Marshal.allocTaskMem分配它。用Marshal.FreeCoTaskMem释放它

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


    我几乎涉猎了我在互联网上能找到的一切。如果需要更多信息,请告诉我。我希望这只是我所缺少的一个简单概念。

    将此签名用于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代码中另一个指针的破坏。非常感谢你帮我解决我自己的愚蠢;)!