2016-10-06 15 views
0

外部C++関数をdylibからUnity C#にインポートします。問題の関数は次のようになります。外部関数のためのC#でのバッファとしてのポインタの使用

[DllImport ("librtcmix_embedded")] 
unsafe private static extern int RTcmix_runAudio(void* k, void *outAudioBuffer, int nframes); 

ポインタを取り込み、そのポインタに固定サイズのバッファにオーディオ情報を書き込みます。 OnAudioFilterReadの本体内に、私は、固定サイズのINT *(2048、数のポインタを宣言することができるであろう理想的

void OnAudioFilterRead(float[] data, int channels) 

:私はバッファにこの情報を取ることになっているUnityからC#の機能を有していますサンプルのUnityのオーディオが使用する)を読み込み、それをRTcmix_runaudioのoutAudioBufferパラメータに入力し、そのポインタからの情報をデータのフロート配列にコピーします。

void OnAudioFilterRead(float[] data, int channels) 
{ 
    int *buffer = new int*(2048); //this line is not proper c#, how do I do this? 
    RTcmix_runAudio (null, buffer, 2048); 
    for(int i = 0; i<2048; i++){ 
     data[i] = (float) buffer[i]; 
    } 
} 

しかし、C#で2048のサイズの正しく動作するポインタを取得する方法は実際にはありません。これに関する助け?配列を入力したり、固定構造体を使用しようとする私の試みはすべて、プログラムをクラッシュさせました。

答えて

0

Marshal.AllocHGlobalを使用すると、IntPtrが指す8192バイト(2048 x 32ビットのサンプル)のアンマネージバッファを割り当てて、DLLに渡すことができます。次に、Marshal.Copyを使用して、管理されていないバッファの内容を管理対象のint []にコピーします。私はLinqを使ってバッファをfloat []にキャストしました。 FreeHGlobalでアンマネージバッファを解放します。

私はバッファが4バイトの整数で構成されていると仮定しています。実際にfloatが含まれている場合は、destinationの型をfloat []に変更し、C#は正しいMarshal.Copyを呼び出します。

using System; 
using System.Linq; 
using System.Runtime.InteropServices; 

public static class DLL 
{ 
    [DllImport("librtcmix_embedded")] 
    public static extern int RTcmix_runAudio(IntPtr k, IntPtr outAudioBuffer, int nframes); 
} 

public class MyTest 
{ 
    void OnAudioFilterRead(out float[] data, int channels) 
     { 
      int[] destination = new int[channels]; 
      IntPtr buffer = Marshal.AllocHGlobal(4*channels); 

      DLL.RTcmix_runAudio((IntPtr)0, buffer, channels);    

      Marshal.Copy(buffer, destination, 0, channels); 

      Marshal.FreeHGlobal(buffer); 

      data = destination.Select(item => (float)item).ToArray(); 

     } 
} 
関連する問題