这是我需要从C#传递的C ++消息:
struct LoginMessage:public NMessage { char szUser[ 16 ]; char szPass[ 16 ]; LoginMessage() { msgId = CTRL_SESSION_LOGIN; msgSize = sizeof( LoginMessage ); } }; struct NMessage { DWORD msgSize; union { DWORD msgId; struct { BYTE msgId0; BYTE msgId1; BYTE msgId2; BYTE msgId3; }; }; NMessage() { } BOOL IsLegal() { return msgSize>=sizeof(NMessage) && msgSize
C#中的等价物是什么,以便C ++可以理解这条消息? 非常感谢示例代码。
答案 0 :(得分:1)
回答我自己的问题..
[StructLayout(LayoutKind.Sequential)]
public struct LoginMessage
{
public int msgSize;
public int msgId;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szUser;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szPass;
}
重要的是要注意类属性的顺序,以便发送到c ++的字节数组与它所期望的完全相同。
答案 1 :(得分:0)
看看this。这是一个很好的编组指南。
答案 2 :(得分:0)
查看MSDN上的StructLayout属性。该页面上有一个很好的示例,说明如何创建可以正确编组的结构。您还可以查看http://www.pinvoke.net以查看有关如何定义Windows API结构的不同示例。正确定义结构后,您应该可以使用Marshal.StructureToPtr或Marshal.PtrToStructure。这是一篇简短的文章:http://geekswithblogs.net/taylorrich/archive/2006/08/21/88665.aspx
答案 3 :(得分:0)
我通常使用类似的东西手动序列化数据。
class NMessage {
byte[] buffer;
//ctor to create a new message for sending.
public NMessage(int nSize) {
buffer = new byte[nSize];
Buffer.BlockCopy(BitConverter.GetBytes(nSize), 0, buffer, 0, sizeof(UInt32));
}
//ctor to create msg from received data.
publix NMessage(byte[] buffer) {
this.buffer = buffer;
}
public UInt32 MessageId {
get { return BitConverter.ToUInt32(buffer, 4);
set { Buffer.BlockCopy(BitConverter.GetBytes(value), 0, buffer, 4, sizeof(UInt32)); }
}
...
public Byte MessageId2 {
get { return buffer[6]; }
set { buffer[6] = value; }
}
...
public UInt32 Size {
get { return BitConverter.ToUInt32(buffer, 0) }
}
public Byte[] Buffer {
get { return buffer; }
}
}
class LoginMessage : NMessage {
Encoding encoding = new ASCIIEncoding(); //or whatever encoding you need.
public LoginMessage() : base(16 + 16) {
this.MessageId = CTRL_SESSION_LOGIN;
}
public LoginMessage(NMessage message) : base(message.Buffer) {
}
public string User {
get { return encoding.GetString(buffer, 8, 16); }
set { Buffer.BlockCopy(encoding.GetBytes(value), 0, buffer, 8, 16);
}
public string Pass {
get { return encoding.GetString(buffer, 24, 16); }
set { Buffer.BlockCopy(encoding.GetBytes(value), 0, buffer, 24, 16);
}
}
所以你只需创建新消息,设置它的数据,然后发送Buffer属性。
Send((new LoginMessage {
User = "user",
Pass = "pass",
}).Buffer);
在接收端,如果您有足够的数据,您可以从收到的字节[]构建消息。
byte[] recvBuf = new byte[MAX_RECV];
int recvSize = Receive(recvBuf);
...
var message = new NMessage(recvBuf);
if (message.MessageId == CTRL_SESSION_LOGIN)
var login = new LoginMessage(message);
var user = login.User;
...
这只是一个粗略的概述,代码显然需要清理,因为我将它简化为只展示了这个想法。