I have an unmanaged C++ code
and I want to convert it to managed C# code
, the unmanaged code is shown below, I've searched but I did not find my answer...I want to know the right way for marshaling the below code, I am not sure how to marshal an enum and then reference it in an structure..the MMTPConxNack
structure is a member of a union inside another structure. the hierarchy is shown below:
typedef enum
{
MMTPCnxNckRsn_NoAnswer=-2,
MMTPCnxNckRsn_SendError=-1,
MMTPCnxNckRsn_Ok=0,
MMTPCnxNckRsn_InvalidMember,
MMTPCnxNckRsn_HubNotReady,
MMTPCnxNckRsn_UnknownMember,
MMTPCnxNckRsn_LastCnxTooRecent,
MMTPCnxNckRsn_InvalidVersion,
MMTPCnxNckRsn_InvalidOptions,
MMTPCnxNckRsn_TooManyCnx
} MMTPCnxNckRsn;
typedef struct
{
MMTPCnxNckRsn Reason;
} MMTPConxNack;
typedef struct
{
long Length;
short Type;
union
{
MMTPConxReq ConxReq;
MMTPConxAck ConxAck;
MMTPConxNack ConxNack; // the structure with an enum inside
MMTPErrInd ErrInd;
} Data;
} MMTPMsg;
actually I want to marshal the MMTPConxNack
structure..and I use FieldOffset to define the size. Thanks in advance.
You need a C# enum and struct to match the native ones:
public enum MMTPCnxNckRsn
{
MMTPCnxNckRsn_NoAnswer,
MMTPCnxNckRsn_SendError,
MMTPCnxNckRsn_Ok,
MMTPCnxNckRsn_InvalidMember,
MMTPCnxNckRsn_HubNotReady,
MMTPCnxNckRsn_UnknownMember,
MMTPCnxNckRsn_LastCnxTooRecent,
MMTPCnxNckRsn_InvalidVersion,
MMTPCnxNckRsn_InvalidOptions,
MMTPCnxNckRsn_TooManyCnx
}
public struct MMTPConxNack
{
public readonly MMTPCnxNckRsn Reason;
}
And you marshal it like this:
var managedItem = (MMTPConxNack)Marshal.PtrToStructure(pointer,typeof(MMTPConxNack));
The enum looks like this:
public enum MMTPCnxNckRsn {
MMTPCnxNckRsn_NoAnswer = -2,
MMTPCnxNckRsn_SendError = -1,
MMTPCnxNckRsn_Ok = 0,
MMTPCnxNckRsn_InvalidMember,
MMTPCnxNckRsn_HubNotReady,
MMTPCnxNckRsn_UnknownMember,
MMTPCnxNckRsn_LastCnxTooRecent,
MMTPCnxNckRsn_InvalidVersion,
MMTPCnxNckRsn_InvalidOptions,
MMTPCnxNckRsn_TooManyCnx
}
The containing struct is:
public struct MMTPConxNack {
public MMTPCnxNckRsn Reason;
}
The union is:
[StructLayout(LayoutKind.Explicit)]
public struct MMTPMsgDataUnion
{
[FieldOffset(0)]
public MMTPConxReq ConxReq;
[FieldOffset(0)]
public MMTPConxAck ConxAck;
[FieldOffset(0)]
public MMTPConxNack ConxNack;
[FieldOffset(0)]
public MMTPErrInd ErrInd;
}
This is the tricky part. You use LayoutKind.Explicit
and FieldOffset
to specify that all the members of the C++ union is overlayed on each other. Obviously you need to have definitions for the other 3 types contained in this union, definitions that we cannot see in the C++ code in the question. I presume you already know how to define those.
Once you have the union declared, the final structure is simple:
public struct MMTPMMsg
{
public int Length;
public short Type;
public MMTPMsgDataUnion Data;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.