我在c++中有一个包含char*[]的结构
struct Adapters {
int iAdapterIndex[6];
int iBusNumber[6];
int iDeviceNumber[6];
char *iAdapterName[6];
char *iDisplayName[6];
};
extern "C"
{
__declspec(dllexport) int GET_ADAPTERS_INFO(Adapters* send)
{
.........
for (int i = 0; i < 6; i++)
{
if (lpAdapterInfo[i].iBusNumber > -1)
{
send->iAdapterIndex[i] = lpAdapterInfo[i].iAdapterIndex;
send->iBusNumber[i] = lpAdapterInfo[i].iBusNumber;
send->iDeviceNumber[i] = lpAdapterInfo[i].iDeviceNumber;
send->iAdapterName[i] = lpAdapterInfo[i].strAdapterName;
send->iDisplayName[i] = lpAdapterInfo[i].strDisplayName;
}
}
return 0;
}
}
我调用一个函数将这个结构传递给c#
[StructLayout(LayoutKind.Sequential)]
public struct Adapters
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iAdapterIndex;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iBusNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iDeviceNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] iAdapterName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] iDisplayName;
};
[DllImport("Example.dll", EntryPoint = "GET_ADAPTERS_INFO", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern int GET_ADAPTERS_INFO(out Adapters adapters);
但是最后我在char*数组中得到了垃圾。我尝试过不同的UnmanagedType,但没有成功。该怎么办?
UPD 1:
[StructLayout(LayoutKind.Sequential)]
public struct Adapters
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iAdapterIndex;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iBusNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] iDeviceNumber;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPTStr, SizeConst = 6)]
public string[] iAdapterName;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPTStr, SizeConst = 6)]
public string[] iDisplayName;
};
它将导致应用程序崩溃
你的C结构体包含char指针数组。char指针数组不是字符数组。
然而,你的c#结构体声明了字符数组。
所以,"垃圾"你在c# struct char数组中看到的实际上是组成C struct char指针数组中的指针值的字节,它被编组器解释为char值。
我不完全确定你应该做什么。但是,请注意以下几点:在缺少原生字符串类型的C语言中,char指针通常用于处理字符串。您可以将char指针数组看作字符串数组。(iAdapterName和iDisplayName可以看作是由六个字符串组成的数组。)因此,我倾向于建议你的c#结构应该定义字符串数组,而不是字符数组。(不确定是否需要显式指定UnmanagedType。LPTStr或类似的MarshalAs属性的ArraySubType
字段)