我正在尝试编组以下结构
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 包装器也不愿那样做。