本人刚学这方面的dd。大概需要实现这样的程序:VC6和C#之间需要用socket通信,互相发些报文,格式都是用结构体定义的,看了些资料,说是要用到下面的两个方法
static object BytesToStruct(byte[] bytes, Type strcutType)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
} static byte[] StructToBytes(object structObj)
{
int size = Marshal.SizeOf(structObj);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structObj, buffer, false);
byte[] bytes = new byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
} }
现在还有几个疑问,想问下大虾们
1 C#发给VC的报文,struct是不是不用StructToBytes转成byte,直接用System.Text.Encoding.BigEndianUnicode.GetBytes就可以了??
2 VC发过来的报文是需要用BytesToStruct吧byte转成struct吗?
3 发送和接受 有什么方法send和read之类的吗?NetworkStream????总之脑子有点乱,帮忙给缕缕,思路代码统统欢迎!!分不多了呵呵,望见谅!
static object BytesToStruct(byte[] bytes, Type strcutType)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
} static byte[] StructToBytes(object structObj)
{
int size = Marshal.SizeOf(structObj);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structObj, buffer, false);
byte[] bytes = new byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
} }
现在还有几个疑问,想问下大虾们
1 C#发给VC的报文,struct是不是不用StructToBytes转成byte,直接用System.Text.Encoding.BigEndianUnicode.GetBytes就可以了??
2 VC发过来的报文是需要用BytesToStruct吧byte转成struct吗?
3 发送和接受 有什么方法send和read之类的吗?NetworkStream????总之脑子有点乱,帮忙给缕缕,思路代码统统欢迎!!分不多了呵呵,望见谅!
开始是放在这里的:
public struct struct1
{
public uint dwSourceIP; //服务器端ip
public uint dwDestinationIP; //客户端ip
public struct1(int i) // 初始化
{
this.dwSourceIP = 0xDA02030A;
this.dwDestinationIP = 0xDA020301;
}
}
这样好像没有把数据传过来,后来就放在StructToBytes前面了。
上面红字的地方其实int i是没有用到的,我的这个结构体里面只是uint的,只是提示错误 1 结构不能包含显式的无参数构造函数,才加上的。
还有就是十六进制的数据0xDA02030A 传过来变成十进制的了。。
不论十进制还是十六进制,都是你看到的表象。
使用反射,这样:(假设你的结构体叫struct1) foreach (FieldInfo pi in struct1.GetType().GetFields())
{
richTextBox1.AppendText(pi.Name + ":" + pi.GetValue(struct1) + "\r\n");
}
====>
当然不行。
socket发送c++中的struct,其实是对struct对象所在的一段内存数据发过来。
而System.Text.Encoding.BigEndianUnicode.GetBytes是将字符串转化为二进制流。
2 VC发过来的报文是需要用BytesToStruct吧byte转成struct吗?
对。
也可以对发过来的数据进行解析,然后new一个C#中的struct对象。
如:
vc中的struct定义如下:
// 假设内存边界对齐为1
struct cpp_struct{
int x;
int y;
};
用socket发送cpp_struct的对象,C#接收到之后,解析前4个字节为x, 后4个字节为y,然后根据x, y,new一个csharp_struct出来。3 发送和接受 有什么方法send和read之类的吗?NetworkStream????
System.Net.Sockets命名空间下有很多有用的类可以用。如:Socket, NetworkStream, TcpClient或者TcpListener。vc的话,当然是用winsock啦.
下面是刚才csdn里搜的
你说的用unsafe代码是这个意思吗?
————————————————————————
如下定义结构:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct pack_LogOn
{
byte byFlag;
byte bySystemID;
byte byFlagType;
byte byReserve;
ushort uSize;
byte byDataID;
ushort uBureauID;
ushort uFCS;
public unsafe byte[] GetBytes()
{
byte[] arr = new byte[ sizeof(pack_LogOn) ];
fixed( byte* parr = arr )
{ *((pack_LogOn*)parr) = this; }
return arr;
}
}
请注意StructLayout的用法和public unsafe byte[] GetBytes()
数据发送代码如下:
pack_LogOn pack=new pack_LogOn;
//填入数据
Byte[] sendBytes = pack.GetBytes();
socket.Send(sendBytes, sendBytes.Length, SocketFlags.None);
把byte[]转为结构是这样的,以上面那个结构为例:
pack_LogOn pack;
fixed(byte* pbuf=buf)
{
pack=*(pack_LogOn)pbuf;
}
除了那些unsafe相关的语句,跟C++里基本一样