日期:2014-05-20  浏览次数:21132 次

C# 使用Union遇到的一个问题。
我在使用联合时,发现问题如下:
情况1:
[StructLayout(LayoutKind.Explicit, Size = 32)]
public struct RCV_FILE_HEADEx_union
{
  [FieldOffset(0)]
  public UInt32 m_dwSerialNo;// 序列号,对股评
  [FieldOffset(0)]
  public byte m_FileTime;// 文件创建时间
}
即使2个字段长度不同也能正常执行。

情况2:
[StructLayout(LayoutKind.Explicit, Size = 144)]
public struct RCV_DATA_union
{
  [FieldOffset(0)]
  public RCV_REPORT_STRUCTEx m_pReport;
  [FieldOffset(0)]
  public RCV_REPORT_STRUCTExV2 m_pReportV2;
}
自定义的Struct在运行时出错,错误如下:未能从程序集“服务器端程序, Version=1.0.2914.26500, Culture=neutral, PublicKeyToken=null”中加载类型“RCV_DATA_union”,因为它在 0 偏移位置处包含一个对象字段,该字段已由一个非对象字段不正确地对齐或重叠。

附上2个自定义的结构:
public struct RCV_REPORT_STRUCTEx
{
UInt16 m_wMarket; // 股票市场类型
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
byte[] m_szLabel; // 股票代码,以'\0'结尾
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
byte[] m_szName; // 股票名称,以'\0'结尾
float m_fLastClose; // 昨收
float m_fOpen; // 今开
float m_fHigh; // 最高
float m_fLow; // 最低
float m_fNewPrice; // 最新
float m_fVolume; // 成交量
float m_fAmount; // 成交额
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
float[] m_fBuyPrice; // 申买价1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
float[] m_fBuyVolume; // 申买量1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
float[] m_fSellPrice; // 申卖价1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
float[] m_fSellVolume; // 申卖量1,2,3
};



//////////////////////////////////////////////////////////////////////////////////
//行情数据(版本2数据结构RCV_WORK_SENDMSG)
//SIZE:144
public struct RCV_REPORT_STRUCTExV2
{
  UInt16 m_cbSize; // 结构大小
  long m_time; // 交易时间
  UInt16 m_wMarket; // 股票市场类型
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  byte[] m_szLabel; // 股票代码,以'\0'结尾
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
  byte[] m_szName; // 股票名称,以'\0'结尾

  float m_fLastClose; // 昨收
  float m_fOpen; // 今开
  float m_fHigh; // 最高
  float m_fLow; // 最低
  float m_fNewPrice; // 最新
  float m_fVolume; // 成交量
  float m_fAmount; // 成交额

  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  float[] m_fBuyPrice; // 申买价1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  float[] m_fBuyVolume; // 申买量1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  float[] m_fSellPrice; // 申卖价1,2,3
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  float[] m_fSellVolume; // 申卖量1,2,3

  float m_fBuyPrice4; // 申买价4
  float m_fBuyVolume4; // 申买量4
  float m_fSellPrice4; // 申卖价4
  float m_fSellVolume4; // 申卖量4
};

请问问题出在哪?



------解决方案--------------------
完全不懂,up


不知道这个指针能对应到类对象
------解决方案--------------------
不是很了解,胡说几句

.net中所有数组为引用类型,不是值类型,把所有数组改为IntPtr是否可行,用时使用Marshal.Copy对指针进行操作不知是否可行,void*是否也可用IntPtr代替。没有什么实践经验随便说说,不对的话就算了。

------解决方案--------------------
以上是一段C++代码,其中的Void *怎么翻译成C#呢?

可以用 IntPtr

另外,实际上Union在内存里只占里面一个变量的地址空间
所以其实你要用哪个就翻译哪个就好了
------解决方案--------------------