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

Posted

技术标签:

【中文标题】如何正确地将浮点指针从 C 库传递到其 C# 包装器【英文标题】:how to properly pass a float pointer from a C library to its C# wrapper 【发布时间】:2014-04-09 22:50:03 【问题描述】:

我的自定义 C 库中有一个函数,它返回一个指向浮点数的指针。 (这实际上是一个包含音频值的浮点数组)。

我想在 Unity3d 中使用这个 C 库(并返回浮点数组),所以我正在为它编写一个 C# 包装器。如何在我的 c# 脚本中正确导入/声明我的 C 函数?

我的 C 声明如下所示:

float*  getAudioBuffer(mySynth_t synth);

在 C# 中,我的猜测是我应该将导入的函数声明为返回 float[],如下所示:

[DllImport (dll)]
private static extern float[]  getAudioBuffer(  IntPtr synth)

正确吗? 我应该使用ref 关键字吗?我应该在某处使用out 关键字吗? 我熟悉 C++,但对 C# 完全不熟悉,所以我不太了解编组等。

浮点数组中的数据也是音频数据,用于填充 OnFilterRead 中 Unity3d 的音频缓冲区。所以这会被调用很多次。 任何关于最佳实践的提示、示例代码或指针都将不胜感激。

【问题讨论】:

首先研究 pinvoke:msdn.microsoft.com/en-us/library/bd99e6zt.aspx。这不是一件容易的事。 【参考方案1】:

我是这样做的:

[DllImport (dll)]
private static extern IntPtr  getAudioBuffer(  IntPtr synth);

然后使用它:

private float[] buffer = new float[1024];

void OnAudioFilterRead (float[] data, int channels)  
    
         IntPtr buf = getAudioBuffer();

         Marshal.Copy(buf, buffer, 0, buffer.Length);
          int i, j;
           for ( i = 0, j=0; j < buffer.Length; i = i + channels, j++)
            
              data[i] = buffer[j];
              if (channels ==2)
                 data [i + 1] = data [i]; 
                   
    

欢迎任何关于如何更有效地做到这一点的提示。

一些不错的读物:here、here 和 here。

【讨论】:

以上是关于如何正确地将浮点指针从 C 库传递到其 C# 包装器的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将日期时间从 c# 传递到 sql?

通过 python 扩展/包装器传递浮点数组指针 – SndObj-library

无法从 Fortran 90 中返回的 C 浮点指针获取数据

如何将 C# 中的方法指针传递给 C 库?

如何使用 Mono Project 将 C/C++ 指针传递和保存到 C#,并将它们返回

如何安全地将字符串引用从 c# 传递到 c++?