タイトルがわかりにくいけど、C#からCで作ったdllに固定長の配列を渡す方法。 ここでは無理やりunsafeを使ってやったけど、もう少しスマートな方法。
構造体をこんな風に書く。
1 2 3 4 5 6 7 8 9 10 11 |
public struct sdrplay_api_DeviceT { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] SerNo; public byte hwVer; public sdrplay_api_TunerSelectT tuner; public sdrplay_api_RspDuoModeT rspDuoMode; public byte valid; public double rspDuoSampleFreq; public IntPtr dev; } |
こうすると、SerNoは64バイトに固定されるみたい。
この構造体を参照渡しで渡してやると、正常に動く。
1 2 |
[DllImport("sdrplay_api.dll", EntryPoint = "sdrplay_api_GetDevices", CallingConvention = CallingConvention.Cdecl)] private static extern sdrplay_api_ErrT sdrplay_api_GetDevices(out sdrplay_api_DeviceT devices, ref uint numdevs, uint maxDevs); |
Cで書かれたサンプルでは、DeviceT構造体の配列を渡しているけど、今回の方法ではDeviceTの配列のサイズを求めようとMarshal.SizeOfを使うと例外が発生してうまくいかない。
実際には、複数のSDRPlayが複数接続されることはないので、とりあえずこのまま進める。