C#调用dll形参问题

问题遇到的现象和发生背景

在C++中调用dll中的这个函数如此定义typedef DWORD(*OpteeQ_GetDeviceList)(OUT char lDevList[][256]);
在C#如何调用试了

[System.Runtime.InteropServices.DllImport("OpteeQ_DLL.dll")]
        private static extern bool OpteeQ_GetDeviceList(ref 
           byte [][]lpAppName// 返回设备列表
  );
///调用
byte[][] devicenum = new byte[8][];
            if (OpteeQ_GetDeviceList(ref devicenum))
                MessageBox.Show("成功");
            else
                MessageBox.Show("失败");

会报错:System.Runtime.InteropServices.MarshalDirectiveException:“无法封送处理“parameter #1”: 嵌套的数组不支持封送处理。”
请教各位,如何处理

数组本身是引用类型,你修改了数组它实参也会变,所以不需要ref关键字
但是注意你要在函数外面new它,不要放进里面new,第2维可以在里面new
-=-=-=
你这是c#调用c++的dll,那么形参必须符合函数本身的类型
c++里根本没有ref关键字,不要瞎搞

由于 C# 不支持嵌套数组的封送,因此您可以在 C# 中定义一个结构体,该结构体包含一个长度为 256 的字符数组。然后,在 C++ 中调用该函数时,可以将每个结构体封送到该数组中。以下是您可以在 C# 中实现的代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DeviceInfo
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string name;
}

[DllImport("OpteeQ_DLL.dll")]
private static extern bool OpteeQ_GetDeviceList(out DeviceInfo[] lpAppName);

DeviceInfo[] devicenum = new DeviceInfo[8];
if (OpteeQ_GetDeviceList(out devicenum))
MessageBox.Show("成功");
else
MessageBox.Show("失败");

请使用 IntPtr 类型代替 byte[][] 类型,并在调用 DLL 之前分配内存。然后,在调用 DLL 后,使用 Marshal.Copy 将 IntPtr 转换为 byte[],最后使用字符串解码 byte[]。示例代码:

[System.Runtime.InteropServices.DllImport("OpteeQ_DLL.dll")]
private static extern bool OpteeQ_GetDeviceList(IntPtr lpAppName, ref int length);

IntPtr lpAppName = Marshal.AllocHGlobal(256 * 8);
int length = 256 * 8;
if (OpteeQ_GetDeviceList(lpAppName, ref length)) {
byte[] buffer = new byte[length];
Marshal.Copy(lpAppName, buffer, 0, length);
string[] devices = Encoding.UTF8.GetString(buffer).Split('\0');
MessageBox.Show("成功");
} else {
MessageBox.Show("失败");
}
Marshal.FreeHGlobal(lpAppName);

如果我的回答对您有帮助请及时采纳谢谢

参考一下


https://blog.csdn.net/bcbobo21cn/article/details/70477626

代码贴出来,调试一下试试看。

一个C#中从C++ DLL中读取二维数组的代码:

定义C++ DLL函数的C#声明:


[DllImport("CppDll.dll")]
private static extern IntPtr Get2DArray();

定义C#结构体,用于表示C++ DLL中的二维数组:

[StructLayout(LayoutKind.Sequential)]
private struct CppArray
{
  public int rows;
  public int cols;
  public IntPtr data;
}


调用C++ DLL函数并将结果转换为C#二维数组:

CppArray cppArray = (CppArray)Marshal.PtrToStructure(Get2DArray(), typeof(CppArray));
int[,] cSharpArray = new int[cppArray.rows, cppArray.cols];
Marshal.Copy(cppArray.data, cSharpArray, 0, cppArray.rows * cppArray.cols);