我正在尝试编组以下结构
struct OpalMessage {
  OpalMessageType m_type;   ///< Type of message
  union {
    const char *             m_commandError;       ///< Used by OpalIndCommandError
    OpalParamGeneral         m_general;            ///< Used by OpalCmdSetGeneralParameters
    OpalParamProtocol        m_protocol;           ///< Used by OpalCmdSetProtocolParameters
    OpalParamRegistration    m_registrationInfo;   ///< Used by OpalCmdRegistration
    OpalStatusRegistration   m_registrationStatus; ///< Used by OpalIndRegistration
    OpalParamSetUpCall       m_callSetUp;          ///< Used by OpalCmdSetUpCall/OpalIndProceeding/OpalIndAlerting/OpalIndEstablished
    const char *             m_callToken;          ///< Used by OpalCmdHoldcall/OpalCmdRetrieveCall/OpalCmdStopRecording
    OpalStatusIncomingCall   m_incomingCall;       ///< Used by OpalIndIncomingCall
    OpalParamAnswerCall      m_answerCall;         ///< Used by OpalCmdAnswerCall/OpalCmdAlerting
    OpalStatusUserInput      m_userInput;          ///< Used by OpalIndUserInput/OpalCmdUserInput
    OpalStatusMessageWaiting m_messageWaiting;     ///< Used by OpalIndMessageWaiting
    OpalStatusLineAppearance m_lineAppearance;     ///< Used by OpalIndLineAppearance
    OpalStatusCallCleared    m_callCleared;        ///< Used by OpalIndCallCleared
    OpalParamCallCleared     m_clearCall;          ///< Used by OpalCmdClearCall
    OpalStatusMediaStream    m_mediaStream;        ///< Used by OpalIndMediaStream/OpalCmdMediaStream
    OpalParamSetUserData     m_setUserData;        ///< Used by OpalCmdSetUserData
    OpalParamRecording       m_recording;          ///< Used by OpalCmdStartRecording
    OpalStatusTransferCall   m_transferStatus;     ///< Used by OpalIndTransferCall
    OpalStatusIVR            m_ivrStatus;          ///< Used by OpalIndCompletedIVR
  } m_param;
};
转到 C#。明显的问题是这两个字符串不可避免地是引用类型。
所以,我尝试了这个:
    [StructLayout(LayoutKind.Explicit)]
    public struct OpalMessageStrUnion
    {
      [FieldOffset(0)]
      [MarshalAs(UnmanagedType.LPStr)]
      public string m_commandError;       ///< Used by OpalIndCommandError
      [FieldOffset(0)]
      [MarshalAs(UnmanagedType.LPStr)]
      public string m_callToken;          ///< Used by OpalCmdHoldcall/OpalCmdRetrieveCall/OpalCmdStopRecording
    }
    [StructLayout(LayoutKind.Explicit)]
    public struct OpalMessageUnion
    {
      [FieldOffset(0)]      
      public OpalParamGeneral m_general;            ///< Used by OpalCmdSetGeneralParameters
      [FieldOffset(0)]
      public OpalParamProtocol m_protocol;           ///< Used by OpalCmdSetProtocolParameters
      [FieldOffset(0)]
      public OpalParamRegistration m_registrationInfo;   ///< Used by OpalCmdRegistration
      [FieldOffset(0)]
      public OpalStatusRegistration m_registrationStatus; ///< Used by OpalIndRegistration
      [FieldOffset(0)]
      public OpalParamSetUpCall m_callSetUp;          ///< Used by OpalCmdSetUpCall/OpalIndProceeding/OpalIndAlerting/OpalIndEstablished     
      [FieldOffset(0)]
      public OpalStatusIncomingCall m_incomingCall;       ///< Used by OpalIndIncomingCall
      [FieldOffset(0)]
      public OpalParamAnswerCall m_answerCall;         ///< Used by OpalCmdAnswerCall/OpalCmdAlerting
      [FieldOffset(0)]
      public OpalStatusUserInput m_userInput;          ///< Used by OpalIndUserInput/OpalCmdUserInput
      [FieldOffset(0)]
      public OpalStatusMessageWaiting m_messageWaiting;     ///< Used by OpalIndMessageWaiting
      [FieldOffset(0)]
      public OpalStatusLineAppearance m_lineAppearance;     ///< Used by OpalIndLineAppearance
      [FieldOffset(0)]
      public OpalStatusCallCleared m_callCleared;        ///< Used by OpalIndCallCleared
      [FieldOffset(0)]
      public OpalParamCallCleared m_clearCall;          ///< Used by OpalCmdClearCall
      [FieldOffset(0)]
      public OpalStatusMediaStream m_mediaStream;        ///< Used by OpalIndMediaStream/OpalCmdMediaStream
      [FieldOffset(0)]
      public OpalParamSetUserData m_setUserData;        ///< Used by OpalCmdSetUserData
      [FieldOffset(0)]
      public OpalParamRecording m_recording;          ///< Used by OpalCmdStartRecording
      [FieldOffset(0)]
      public OpalStatusTransferCall m_transferStatus;     ///< Used by OpalIndTransferCall
      [FieldOffset(0)]
      public OpalStatusIVR m_ivrStatus;          ///< Used by OpalIndCompletedIVR
    }
    /// <summary>
    /// Message to/from OPAL system.
    /// This is passed via the OpalGetMessage() or OpalSendMessage() functions.
    /// </summary> 
    [StructLayout(LayoutKind.Explicit)]
    public struct OpalMessage
    {
      //this guy is an enumeration b.t.w.
      /// <summary>
      /// type of message
      /// </summary> 
      [FieldOffset(0)]
      public OpalMessageType m_type;
      [FieldOffset(4)]
      public OpalMessageUnion m_param;
      [FieldOffset(4)]
      public OpalMessageStrUnion m_strParam;
    }
但是,我仍然收到封送处理错误,告诉我这不起作用,因为我将对象与非对象类型混合在同一内存位置。我现在假设结构本身(即 OpalParamGeneral 等)也不能混合引用和值类型,即使它们是按顺序排列的?
顺便说一下,对每个结构进行单独的函数调用不是一种选择。我宁愿写一个 COM 包装器也不愿那样做。