最近做一个PowerShell的项目, 其中做了很多了cmdlet命令, 为实现一些功能, 自己又做了不少C的方法封在DLL里, 供C#调用.其中有这样一个结构:
typedef struct _ABOUT_INFO_OBJ
{
ULONG nLicenseType;
union
{
ULONG nClientCount;
ULONG nErrorCode;
};
CHAR pchSerialNo[64];
union
{
struct
{
INT nDaysLeft;
}Trial;
struct
{
CHAR pchName[64];
CHAR pchCompName[256];
union
{
INT nDaysLeft;
}TimeLimit;
union
{
}Infinite;
}Registed;
};
} ABOUT_INFO_OBJ, *PABOUT_INFO_OBJ;
我用C#是这样封的:
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct ABOUT_INFO_OBJ
{
[FieldOffset(0)]
public UInt32 nLicenseType;
[FieldOffset((int)(sizeof(UInt32)))]
public UnionPart_1 m_UnionPart_1;
[FieldOffset((int)(sizeof(UInt32) * 2))]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string pchSerialNo;
[FieldOffset((int)(sizeof(UInt32) * 2) + 64)]
public UnionPart_2 m_UnionPart_2;
}
[StructLayout(LayoutKind.Explicit, Size = (int)(sizeof(int)))]
public struct UnionPart_1
{
[FieldOffset(0)]
public UInt32 nClientCount;
[FieldOffset(0)]
public UInt32 nErrorCode;
}
[StructLayout(LayoutKind.Explicit, Size = (int)(64 + 256 + sizeof(Int32)))]
public struct UnionPart_2
{
[FieldOffset(0)]
public UnionPart_2_1 Trial;
[FieldOffset(0)]
public UnionPart_2_2 Registed;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct UnionPart_2_1
{
public Int32 nDaysLeft;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct UnionPart_2_2
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string pchName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string pchCompName;
public UnionPart_2_2_1 TimeLimit;
public UnionPart_2_2_2 Infinite;
}
[StructLayout(LayoutKind.Explicit, Size = (int)(sizeof(int)))]
public struct UnionPart_2_2_1
{
[FieldOffset(0)]
public int nDaysLeft;
}
[StructLayout(LayoutKind.Explicit, Size = 0)]
public struct UnionPart_2_2_2
{
}
随后我将用C#做好的cmdlet DLL文件Add到本地powershell环境中, (Add-PSSnapin xxxxx.PowerShell.Commands), 此时报了个错:
Add-PSSnapin : 未能从程序集“xxxxxPowerShell, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中加载类型“UnionPart_2”,因为它在 0 偏移位置处包含一个对象字段,该字段已由一个非对象字段不正确地对齐或重叠。
所在位置 行:1 字符: 1
+ Add-PSSnapin xxxxx.PowerShell.Commands
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-PSSnapin], TypeLoadException
+ FullyQualifiedErrorId : System.TypeLoadException,Microsoft.PowerShell.Commands.AddPSSnapinCommand
问题就在名为 UnionPart_2 的机构体, 把它注释掉, powershell就正常添加模块了. 以往我也定义过这种嵌套的Union(联合体), 想请大家帮我看看问题出在那里, 是用C#定义嵌套的结构体不对, 还是powershell里有限制?