将浮点数组从 C++ 获取到 C#

Posted

技术标签:

【中文标题】将浮点数组从 C++ 获取到 C#【英文标题】:Getting float array from C++ to C# 【发布时间】:2017-12-06 14:37:20 【问题描述】:

我在 C++ 函数中有浮点数组。

C++ 函数

void bleplugin_GetGolfResult(float* result)

    float *array = new float[20];
    for(int i=0; i < 20; i++)
      array[i]= 25;
    result = array;
    //DEBUG PRINTING1
    for(int i=0; i < 20; i++)
       cout << result[i] << endl;//Here is correct
    return;

C#内部

[DllImport ("__Internal")]
private static unsafe extern void bleplugin_GetGolfResult (float* result);

public static unsafe float[] result = new float[20];

public unsafe static void GetGolfREsult()
    fixed (float* ptr_result = result) //or equivalently "... = &f2[0]" address of f2[0]
               
        bleplugin_GetGolfResult( ptr_result );
        //DEBUG PRINTING2
        for(int i = 0; i < 20; i++)
            Debug.Log("result data " + ptr_result[i]);
    
    return;

我从另一个函数调用GetGolfREsult() 来获取结果。

//DEBUG PRINTING1 输出正确。

但是//DEBUG PRINTING2 只产生了 0。

可能出了什么问题?

【问题讨论】:

在 C# 方法中为数组赋值的位置在哪里? 永远不要在参数上使用赋值运算符 result 按值传递。因此,分配给它是没有意义的。您的问题在出现任何 C# 代码之前就开始了。您的 C++ 函数目前没有任何用处。你正在超越自己。在尝试从 C++ 调用它之前,请确保您的 C++ 代码有效。而且这里不需要不安全的代码。 如果您可以添加有关数组大小的提示(并按照 David 指出的那样修复您的 C++ 代码),您可以使用in this answer 提供的解决方案。 【参考方案1】:

正如 UnholySheep 和 nvoigt 已经说过的,

result = array;

覆盖传递指针的地址,使您失去对调用函数的引用。

直接写入你的参数应该可以解决这个问题。

result[i] = 25;

此外,您实际上不必在 c# 中使用指针。 您实际上可以执行以下操作:

像这样声明你的导入:

private static extern void bleplugin_GetGolfResult (float arr[]);

那么你可以这样称呼它:

float arr = new float[20];
bleplugin_GetGolfResult(arr);

【讨论】:

【参考方案2】:

C++ 代码中的这一行:

float *array = new float[20];

创建一个新数组,您可以在 C++ 中对其进行操作。然后控制权返回给 C#,C# 拥有自己的数组并且仍然没有改变。你为什么不写你得到的数组呢?

【讨论】:

我认为 OP 的实际缺陷是 result = array; 会将这个数组分配(复制?)回 C# 因为我喜欢将数组数据复制到结果中。你的意思是写我得到的数组。我不明白。 其实我用 float *array 作为一个简单的例子。由于某种原因,该数组已经存在,我不能使用参数结果在 C++ 函数中创建数组。 @batuman result = array; 不会修改传入的数组(如果您只使用 C++ 也不会这样做),它只是将本地指针重定向到数组。您需要直接写入传入的数组(通过result[i] = 25; 而不是array[i] = 25;【参考方案3】:

问题是您在参数结果上使用了赋值运算符,这会阻止数据在返回时传输到 C# 数组。

使用以下 C++ 示例:

void z(int * x)

  x = new int(4);


int main()

  int * x = new int(-2);
  z(x);
  cout<<*x<<endl;

输出是 -2 而不是 4,因为您在参数上使用了赋值运算符。

【讨论】:

我该怎么办? @batuman 可以将一个长度为 20 的数组传递给函数,然后您只需更改数组中每个点的值

以上是关于将浮点数组从 C++ 获取到 C#的主要内容,如果未能解决你的问题,请参考以下文章

C++ 将浮点数保存并加载到二进制文件中,由指针寻址

如何正确地将浮点指针从 C 库传递到其 C# 包装器

在 C# 中“转换”浮点数为双精度值

从文件中读取浮点数/单词/符号并仅将浮点数存储在数组 C++ 中

opencv c++:将图像矩阵从无符号字符转换为浮点数

在 C++ 中正确转换浮点数