C#当中,调用C/C++的函数,其中参数需要传递结构数组,该如何调用?
例如海康SDK当中,NET_DVR_GetDeviceConfig,NET_DVR_GET_MULTI_STREAM_COMPRESSIONCFG获取解码编码信息,返回多个结构数组,如何调用?
public static List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG> GetMultiStreamCompressionCfg(int lUserID)
{
const int MAX_COUNT = 5;
NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND[] InputData = new CHCNetSDK.NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND[MAX_COUNT];
for (uint j = 0; j < MAX_COUNT; j++)
{
InputData[j].dwSize = (uint)Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND));
InputData[j].struStreamInfo.dwChannel = 1;
InputData[j].struStreamInfo.dwSize = (uint)Marshal.SizeOf(typeof(NET_DVR_STREAM_INFO));
InputData[j].dwStreamType = j;
}
int inSize = InputData.Length * Marshal.SizeOf(InputData[0]);
IntPtr input = Marshal.AllocHGlobal(inSize);
for (int i = 0; i< InputData.Length; i++)
{
IntPtr newPtr = new IntPtr(input.ToInt32() + i * Marshal.SizeOf(InputData[0]));
Marshal.StructureToPtr(InputData[i], newPtr, true);
}
IntPtr status = Marshal.AllocHGlobal(4 * MAX_COUNT);
List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG> OutputData = new List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG>();
int outSize = MAX_COUNT * Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG));
IntPtr output = Marshal.AllocHGlobal(outSize);
bool ret = CHCNetSDK.NET_DVR_GetDeviceConfig(lUserID, CHCNetSDK.NET_DVR_GET_MULTI_STREAM_COMPRESSIONCFG, MAX_COUNT, input, (uint)inSize, status, output, (uint)outSize);
if (ret)
{
for (int i=0; i < MAX_COUNT; i++)
{
int b = Marshal.ReadInt32(status, i * 4);
if (b == 0 || b == 1)
{
IntPtr newPtr = new IntPtr(output.ToInt32() + i * Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG)));
NET_DVR_MULTI_STREAM_COMPRESSIONCFG stru = (NET_DVR_MULTI_STREAM_COMPRESSIONCFG) Marshal.PtrToStructure(newPtr, typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG));
OutputData.Add(stru);
}
}
}
return OutputData;
}
public static bool SetMultiStreamCompressionCfg(int lUserID, List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG> cfgs)
{
int MAX_COUNT = cfgs.Count;
NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND[] InputData = new CHCNetSDK.NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND[MAX_COUNT];
for (int j = 0; j < MAX_COUNT; j++)
{
InputData[j].dwSize = (uint)Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG_COND));
InputData[j].struStreamInfo.dwChannel = 1;
InputData[j].struStreamInfo.dwSize = (uint)Marshal.SizeOf(typeof(NET_DVR_STREAM_INFO));
InputData[j].dwStreamType = cfgs[j].dwStreamType;
}
int inSize = InputData.Length * Marshal.SizeOf(InputData[0]);
IntPtr input = Marshal.AllocHGlobal(inSize);
for (int i = 0; i < InputData.Length; i++)
{
IntPtr newPtr = new IntPtr(input.ToInt32() + i * Marshal.SizeOf(InputData[0]));
Marshal.StructureToPtr(InputData[i], newPtr, true);
}
IntPtr status = Marshal.AllocHGlobal(4 * MAX_COUNT);
List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG> OutputData = new List<NET_DVR_MULTI_STREAM_COMPRESSIONCFG>();
int outSize = MAX_COUNT * Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG));
IntPtr output = Marshal.AllocHGlobal(outSize);
for (int i=0; i< MAX_COUNT; i++)
{
IntPtr newPtr = new IntPtr(output.ToInt32() + i * Marshal.SizeOf(typeof(NET_DVR_MULTI_STREAM_COMPRESSIONCFG)));
Marshal.StructureToPtr(cfgs[i], newPtr, true);
}
bool ret = true;
ret &= CHCNetSDK.NET_DVR_SetDeviceConfig(lUserID, CHCNetSDK.NET_DVR_SET_MULTI_STREAM_COMPRESSIONCFG, (uint)MAX_COUNT, input, (uint)inSize, status, output, (uint)outSize);
if (ret)
{
for (int i = 0; i < MAX_COUNT; i++)
{
int b = Marshal.ReadInt32(status, i * 4);
ret &= (b == 0 || b == 1);
}
}
return ret;
}