次の構造をマーシャリングしようとしています
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# に移行します。明らかな問題は、必然的に参照型になる 2 つの文字列です。
だから、私はこれを試しました:
[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ラッパーを作成したいと思います。