I am trying to marshall the following structure
struct OpalMessage {
OpalMessageType m_type;
union {
const char * m_commandError;
OpalParamGeneral m_general;
OpalParamProtocol m_protocol;
OpalParamRegistration m_registrationInfo;
OpalStatusRegistration m_registrationStatus;
OpalParamSetUpCall m_callSetUp;
const char * m_callToken;
OpalStatusIncomingCall m_incomingCall;
OpalParamAnswerCall m_answerCall;
OpalStatusUserInput m_userInput;
OpalStatusMessageWaiting m_messageWaiting;
OpalStatusLineAppearance m_lineAppearance;
OpalStatusCallCleared m_callCleared;
OpalParamCallCleared m_clearCall;
OpalStatusMediaStream m_mediaStream;
OpalParamSetUserData m_setUserData;
OpalParamRecording m_recording;
OpalStatusTransferCall m_transferStatus;
OpalStatusIVR m_ivrStatus;
} m_param;
};
to c #. The obvious problem is two lines, which will inevitably be reference types.
So, I tried this:
[StructLayout(LayoutKind.Explicit)]
public struct OpalMessageStrUnion
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.LPStr)]
public string m_commandError;
[FieldOffset(0)]
[MarshalAs(UnmanagedType.LPStr)]
public string m_callToken;
}
[StructLayout(LayoutKind.Explicit)]
public struct OpalMessageUnion
{
[FieldOffset(0)]
public OpalParamGeneral m_general;
[FieldOffset(0)]
public OpalParamProtocol m_protocol;
[FieldOffset(0)]
public OpalParamRegistration m_registrationInfo;
[FieldOffset(0)]
public OpalStatusRegistration m_registrationStatus;
[FieldOffset(0)]
public OpalParamSetUpCall m_callSetUp;
[FieldOffset(0)]
public OpalStatusIncomingCall m_incomingCall;
[FieldOffset(0)]
public OpalParamAnswerCall m_answerCall;
[FieldOffset(0)]
public OpalStatusUserInput m_userInput;
[FieldOffset(0)]
public OpalStatusMessageWaiting m_messageWaiting;
[FieldOffset(0)]
public OpalStatusLineAppearance m_lineAppearance;
[FieldOffset(0)]
public OpalStatusCallCleared m_callCleared;
[FieldOffset(0)]
public OpalParamCallCleared m_clearCall;
[FieldOffset(0)]
public OpalStatusMediaStream m_mediaStream;
[FieldOffset(0)]
public OpalParamSetUserData m_setUserData;
[FieldOffset(0)]
public OpalParamRecording m_recording;
[FieldOffset(0)]
public OpalStatusTransferCall m_transferStatus;
[FieldOffset(0)]
public OpalStatusIVR m_ivrStatus;
}
[StructLayout(LayoutKind.Explicit)]
public struct OpalMessage
{
[FieldOffset(0)]
public OpalMessageType m_type;
[FieldOffset(4)]
public OpalMessageUnion m_param;
[FieldOffset(4)]
public OpalMessageStrUnion m_strParam;
}
However, I still get a marshaling error telling me that this will not work, because I am mixing an object with non-object types in the same memory location. I now assume that the structures themselves (i.e. OpalParamGeneral, etc.) also cannot mix reference and value types, even if they are laid out sequentially?
Making a separate function call for each structure is, by the way, not an option. I would rather write a COM wrapper than doing this.