//C++ code
struct _cmdTag
{
unsigned char cmd:4;
unsigned char cmd_type:3;
unsigned char active:1;
};
vod SetCmdFrame(unsigned char* pBuf, unsigned char cmd, unsigned char cmd_type)
{
_cmdTag *pFrame = (_cmdTag*)pBuf;
pFrame->cmd = cmd;
pFrame->cmd_type = cmd_type;
pFrame->active = 0; //主动或被动
...
}
void IsCmdFrame(unsigned char* pBuf)
{
_cmdTag *pFrame = (_cmdTag*)pBuf;
if(pFrame->cmd == CMD_SEND_DATA)
{
...
}
...
}
请问C#如何实现以上代码啊?
67 个解决方案
#1
++ C#
char* string
传出的char* StringBuilder
short short
char byte
char[n] fixed byte[n]
http://topic.csdn.net/u/20110124/18/b5ff89bd-b488-4e7e-bf87-926ab6251968.html
char* string
传出的char* StringBuilder
short short
char byte
char[n] fixed byte[n]
http://topic.csdn.net/u/20110124/18/b5ff89bd-b488-4e7e-bf87-926ab6251968.html
#2
struct _cmdTag
{
byte cmd:4;
byte char cmd_type:3;
byte char active:1;
};
unsafe void SetCmdFrame(byte* pBuf, byte cmd, byte cmd_type)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
pFrame->cmd = cmd;
pFrame->cmd_type = cmd_type;
pFrame->active = 0; //主动或被动
...
}
unsafe void IsCmdFrame(byte* pBuf)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
if(pFrame->cmd == CMD_SEND_DATA)
{
...
}
...
}
{
byte cmd:4;
byte char cmd_type:3;
byte char active:1;
};
unsafe void SetCmdFrame(byte* pBuf, byte cmd, byte cmd_type)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
pFrame->cmd = cmd;
pFrame->cmd_type = cmd_type;
pFrame->active = 0; //主动或被动
...
}
unsafe void IsCmdFrame(byte* pBuf)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
if(pFrame->cmd == CMD_SEND_DATA)
{
...
}
...
}
#3
移植干嘛?如果可能,删除以前的东西吧。重新开始学编程。
#4
如果你深陷于什么性能、空间的纠结里出不来,对你的应用程序(而是简单地一两条语句)进行测试,看看这个纠结值几毛钱,可以不可以不问自己“请问C#如何实现以上代码”的问题的情况下同样完成自己的任务、赢得用户,这就够了。
测试来说了算,不要搞理论。
测试来说了算,不要搞理论。
#5
Ok,删除以前的东西重新用C#编程,
那么C++实现的那个代码,
请问用C#如何实现?
谢谢!
#6
这不是理论,
这是实实在在、普普通通的C++代码,
老哥!
你没写过这方面的代码,
拜托你不要用“理论”一次来形容它好吗?
#7
看不出你链接指向的帖子与我这个问题的联系。
#8
非指针写法
Class _cmdTag
{
public byte cmd;
public byte cmd_type;
public byte active;
public static _cmdTag Convert(Byte[] b)
{
判断b
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
void SetCmdFrame(byte[] pBuf, byte cmd, byte cmd_type)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
pFrame.cmd = cmd;
pFrame.cmd_type = cmd_type;
pFrame.active = 0; //主动或被动
...
}
void IsCmdFrame(byte[] pBuf)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
if(pFrame.cmd == CMD_SEND_DATA)
{
...
}
...
}
Class _cmdTag
{
public byte cmd;
public byte cmd_type;
public byte active;
public static _cmdTag Convert(Byte[] b)
{
判断b
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
void SetCmdFrame(byte[] pBuf, byte cmd, byte cmd_type)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
pFrame.cmd = cmd;
pFrame.cmd_type = cmd_type;
pFrame.active = 0; //主动或被动
...
}
void IsCmdFrame(byte[] pBuf)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
if(pFrame.cmd == CMD_SEND_DATA)
{
...
}
...
}
#9
谢谢您!
不过老哥,
请您先弄明白什么叫做C++的“位域”吧!
#10
C#当前版本不支持位域
#11
要那么严格的话,C#好像做不到
#12
凡是把下面代码:
//C++ code
struct _cmdTag
{
unsigned char cmd:4;
unsigned char cmd_type:3;
unsigned char active:1;
};
理解为:
struct _cmdTag
{
unsigned char cmd[4];
unsigned char cmd_type[3];
unsigned char active[1];
};
或者:
struct _cmdTag
{
unsigned char[4] cmd;
unsigned char[3] cmd_type;
unsigned char[1] active;
};
请,先弄明白C++的“位域”,
谢谢!
//C++ code
struct _cmdTag
{
unsigned char cmd:4;
unsigned char cmd_type:3;
unsigned char active:1;
};
理解为:
struct _cmdTag
{
unsigned char cmd[4];
unsigned char cmd_type[3];
unsigned char active[1];
};
或者:
struct _cmdTag
{
unsigned char[4] cmd;
unsigned char[3] cmd_type;
unsigned char[1] active;
};
请,先弄明白C++的“位域”,
谢谢!
#13
看来这个小问题,
竟然遇到大麻烦了,
老板让我们转到C#,
看来C#并不能完成C++所能完成的全部功能啊。
#14
从应用的层面来说,一个语言能够实现的功能,几乎都能够用其它任何一种合格的语言来实现,其区别只有编码效率和运行效率的区别。就像SP1234说的,不要纠结这些细节,用C#重写一次就行了
#15
帮你查到一篇,是这个
http://topic.csdn.net/t/20030531/22/1860471.html
http://topic.csdn.net/t/20030531/22/1860471.html
#16
微软不是号称C#无所不能吗,
能完成C++所有的功能吗?
晕,到底转向C#可以吗?
#17
我丝毫不像纠结于什么细节,
我就想知道C#该如何重写它,
仅此而已!
#18
“微软不是号称C#无所不能吗,”,没听说过啊。
#19
udp组包的时候用过,原来这个叫位域啊
上面这个帖子牛,想到枚举
上面这个帖子牛,想到枚举
#20
谢谢!那个帖子的问题与我这个问题有相似的地方,
但是它那是用C#的枚举解决问题,
但这是不行的,例如:
struct _cmdTag
{
unsigned int cmd:4;
unsigned int active:1;
unsigned int frame_len:27;
};
就没法解决,因为frame_len是表示27bit的整数值。
#21
用枚举不行,请看我的帖子。
#22
这些拿微软一些控件来写界面的所谓“程序员”,
真让人抓狂啊,
还怪别人搞些“理论的东西”!
#23
以前用c组过mac帧,的确比c#方便很多,后来再做都是用整形和字符串组byte,没想到什么好办法
#24
http://archive.cnblogs.com/a/1942446/
#25
脑筋不要这么死板好不好,c++有位域,c#就一定要支持?那要让你把C++的代码给改成perl的,你不是要抓狂了。
你那个结构用C#写成下面这样,浪费一点空间不就完了,active的类型也可以改成bool。移植程序嘛,灵活一点。要是什么都完全一样,就用不着移植了
struct _cmdTag
{
unsigned char cmd;
unsigned char cmd_type;
unsigned char active;
};
你那个结构用C#写成下面这样,浪费一点空间不就完了,active的类型也可以改成bool。移植程序嘛,灵活一点。要是什么都完全一样,就用不着移植了
struct _cmdTag
{
unsigned char cmd;
unsigned char cmd_type;
unsigned char active;
};
#26
朋友,你没有写过类似的东西,可能没法理解
例如
void compose(char* buffer)
{
//buffer 是需要out的数据帧 函数内组包
//ether头 结构体
ether_header* eh;
//arp头 结构体
arp_header* ah;
eh = (etherheader*)buffer;
ah = (arp_header*)(buffer+sizeof(ether_header)) ;
eh.dmac =...
...
ah.targetip = ...
这样,在数据帧的各部分结构体的数据赋值完毕之后,buffer也同时填充完毕了
也就是说,如果用了char,那么在buffer中就明显存在了问题,因为原来是1bit的数据你填充了8bit!!!
}
这个问题要从内存角度去理解,个人在C#还没有发现可以达到这种目的的方法,当然可能是我才疏学浅
#27
楼主啊,不管数据帧内各部分是什么,最后组包完毕总是byte的整数倍
所以如果没什么好办法的话,用char或者其他类型作为结构体的成员类型,敷值完毕以后自己计算byte
很傻,不过能做出来
C#有自己的优势,不过底层的东西,还是C比较方便
所以如果没什么好办法的话,用char或者其他类型作为结构体的成员类型,敷值完毕以后自己计算byte
很傻,不过能做出来
C#有自己的优势,不过底层的东西,还是C比较方便
#28
话说好久没写C了,貌似有些写错了,各位看官莫笑
#29
不知道这样行不
class Program
{
static void Main(string[] args)
{
CmdTag ct = new CmdTag(25);
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"],ct["active"]));
ct["cmd"] = 3;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
ct["cmd_type"] = 6;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
ct["active"] = 1;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
CmdTag ct1 = (CmdTag)3;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct1["cmd"], ct1["cmd_type"], ct1["active"]));
Console.ReadLine();
}
}
class CmdTag
{
private byte _v;
//构造函数
public CmdTag() { }
public CmdTag(byte v)
{
_v = v;
}
//强制运算符的重载,将byte转换为CmdTag类型
public static explicit operator CmdTag(byte b)
{
return new CmdTag(b);
}
//索引器
public byte this[string str]
{
//获取字段值
get
{
if (str == "cmd") return (byte)(_v >> 4);
if (str == "cmd_type") return (byte)((_v & 0xf) >> 1);
if (str == "active") return (byte)(_v & 0x01);
throw new Exception(string.Format("不存在字段:{0}", str));
}
//设置字段值
set
{
if (str == "cmd") _v = (byte)((_v&0xf)|(value<<4));
else if (str == "cmd_type") _v =(byte)((_v&0xf1)|(value<<1));
else if (str == "active") _v = (byte)((_v&0xfe)|value);
else throw new Exception(string.Format("不存在字段:{0}",str));
}
}
}
#30
抱歉有点错误
if (str == "cmd") _v = (byte)((_v&0xf)|(value<<4));
else if (str == "cmd_type") _v = (byte)((_v & 0xf1) | ((value << 1) & 0xe));
else if (str == "active") _v = (byte)((_v&0xfe)|(value&0x1));
else throw new Exception(string.Format("不存在字段:{0}",str));
#31
楼上那个写得很好了,我再班门弄斧一下,哈哈
struct _cmdTag
{
public byte b;
public byte cmd()
{
return (byte)(((byte)(b << 4)) >> 4);
}
public byte cmd_type()
{
return (byte)(((byte)(b << 1)) >> 5);
}
public byte active()
{
return ((byte)(b >> 7));
}
}
unsafe static void Main(string[] args)
{
byte* f = stackalloc byte[10];
*f = 248;
_cmdTag* d = (_cmdTag*)f;
Console.WriteLine(d->cmd());
Console.WriteLine(d->cmd_type());
Console.WriteLine(d->active());
Console.ReadLine();
}
struct _cmdTag
{
public byte b;
public byte cmd()
{
return (byte)(((byte)(b << 4)) >> 4);
}
public byte cmd_type()
{
return (byte)(((byte)(b << 1)) >> 5);
}
public byte active()
{
return ((byte)(b >> 7));
}
}
unsafe static void Main(string[] args)
{
byte* f = stackalloc byte[10];
*f = 248;
_cmdTag* d = (_cmdTag*)f;
Console.WriteLine(d->cmd());
Console.WriteLine(d->cmd_type());
Console.WriteLine(d->active());
Console.ReadLine();
}
#32
C#不能直接实现,自己做位运算吧。
#33
C#肯定不能直接提供你想要的这种功能,你需要像后面几位回复写的那样,写一些把结构体转换成字符流的代码。肯定要比C++麻烦,这是语言本身决定了的。还是那句话,要是把这段代码转换成perl,你怎么办?多想办法,多绕弯子嘛,移植的工作量就是在这些东西方面了
#34
#35
try like this
using System;
namespace BitfieldTest
{
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed class BitfieldLengthAttribute : Attribute
{
uint length;
public BitfieldLengthAttribute(uint length)
{
this.length = length;
}
public uint Length { get { return length; } }
}
static class PrimitiveConversion
{
public static long ToLong<T>(T t) where T : struct
{
long r = 0;
int offset = 0;
// For every field suitably attributed with a BitfieldLength
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
{
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
if (attrs.Length == 1)
{
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
// Calculate a bitmask of the desired length
long mask = 0;
for (int i = 0; i < fieldLength; i++)
mask |= 1 << i;
r |= ((UInt32)f.GetValue(t) & mask) << offset;
offset += (int)fieldLength;
}
}
return r;
}
}
struct PESHeader
{
[BitfieldLength(2)]
public uint reserved;
[BitfieldLength(2)]
public uint scrambling_control;
[BitfieldLength(1)]
public uint priority;
[BitfieldLength(1)]
public uint data_alignment_indicator;
[BitfieldLength(1)]
public uint copyright;
[BitfieldLength(1)]
public uint original_or_copy;
};
public class MainClass
{
public static void Main(string[] args)
{
PESHeader p = new PESHeader();
p.reserved = 3;
p.scrambling_control = 2;
p.data_alignment_indicator = 1;
long l = PrimitiveConversion.ToLong(p);
for (int i = 63; i >= 0; i--)
{
Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");
}
Console.WriteLine();
return;
}
}
}
#36
直接的没有。不过间接的方法还是很多的。
#37
你说得倒是好,
改下代码就行吗?
把所有设备的代码都改变吗?
那么请说服大家把TCP等等协议都改变吧!
#38
感觉绕了很大弯,
挺费劲的。
#39
谢谢您的鼎力帮助,
感觉费了挺大的劲儿,
费了九牛二虎之力,
效果还够呛,
看来用C#写底层代码,
还真的不行,
得给老板建议不要转向C#了。
#40
这样的贸然转型确实很危险,以LZ目前对C#的了解,即使转过来,项目或产品的质量也是无法保证的,尤其是涉及这种底层细节,需要有足够经验积累才可以。如果老板非要转的话,LZ可以建议先把一些简单、C#有优势的部分做移植
#41
看来界面部分可以先转到C#,
底层代码还是要用C++。
#42
谢谢!您的方法感觉比较可行,
由于我对C#了解有限,所以代码还需验证。
#43
总算听到了有哲理的话。
#44
算啦吧,不懂装懂,
见过巴掌大的天,
就以为自己的办法天下都通用。
#45
说什么“性能”、“空间”啊之类的话,
我问的问题与性能之类的东西有什么关系呢?
你以为这都是C++的人故意显示自己水平高,
故意造作使用位域吗?
不懂你就别跟着别人屁股后瞎嚷嚷了,
让人看得你的根基有多浅薄。
#46
真晕啊,
问了个位域问题,
硬是让一帮人说C++故意执拗于性能,
故意钻牛角之类显示自己理论多高的样子,
说白了,做应用软件的人,
很难理解底层为什么要这么做,
真是不做一行,不懂一行啊,
希望那些没有做过底层的,
不要再以此来讥讽了,
做C++的并不是为显摆才让代码那样子,
我也知道了C#的局限,
所以转入C#也会深重考虑了。
问了个位域问题,
硬是让一帮人说C++故意执拗于性能,
故意钻牛角之类显示自己理论多高的样子,
说白了,做应用软件的人,
很难理解底层为什么要这么做,
真是不做一行,不懂一行啊,
希望那些没有做过底层的,
不要再以此来讥讽了,
做C++的并不是为显摆才让代码那样子,
我也知道了C#的局限,
所以转入C#也会深重考虑了。
#47
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
#48
好難懂,在學習中
#49
各位仙人非同一般//我也喜欢还是喜欢C
#50
To ChinaOS
非托管 转 托管的时候并不一定要把代码全部重写,也可以试着将非托管的部分封装成dll,给托管代码调用
像bitfield 及 union等最好能通过接口封装掉,不是说C#不能调,而是降低调用的麻烦程度,凡事有个度,具体事情具体衡量。
PS:某些人回答问题最好能看清楚别人问的问题是什么才回答,而不是一上来就否定人家,给出的建议也没什么建树,不知所云,不止在一个帖子里看到这样的回答,忍不住多嘴一句。
非托管 转 托管的时候并不一定要把代码全部重写,也可以试着将非托管的部分封装成dll,给托管代码调用
像bitfield 及 union等最好能通过接口封装掉,不是说C#不能调,而是降低调用的麻烦程度,凡事有个度,具体事情具体衡量。
PS:某些人回答问题最好能看清楚别人问的问题是什么才回答,而不是一上来就否定人家,给出的建议也没什么建树,不知所云,不止在一个帖子里看到这样的回答,忍不住多嘴一句。
#1
++ C#
char* string
传出的char* StringBuilder
short short
char byte
char[n] fixed byte[n]
http://topic.csdn.net/u/20110124/18/b5ff89bd-b488-4e7e-bf87-926ab6251968.html
char* string
传出的char* StringBuilder
short short
char byte
char[n] fixed byte[n]
http://topic.csdn.net/u/20110124/18/b5ff89bd-b488-4e7e-bf87-926ab6251968.html
#2
struct _cmdTag
{
byte cmd:4;
byte char cmd_type:3;
byte char active:1;
};
unsafe void SetCmdFrame(byte* pBuf, byte cmd, byte cmd_type)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
pFrame->cmd = cmd;
pFrame->cmd_type = cmd_type;
pFrame->active = 0; //主动或被动
...
}
unsafe void IsCmdFrame(byte* pBuf)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
if(pFrame->cmd == CMD_SEND_DATA)
{
...
}
...
}
{
byte cmd:4;
byte char cmd_type:3;
byte char active:1;
};
unsafe void SetCmdFrame(byte* pBuf, byte cmd, byte cmd_type)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
pFrame->cmd = cmd;
pFrame->cmd_type = cmd_type;
pFrame->active = 0; //主动或被动
...
}
unsafe void IsCmdFrame(byte* pBuf)
{
_cmdTag* pFrame = (_cmdTag*)pBuf;
if(pFrame->cmd == CMD_SEND_DATA)
{
...
}
...
}
#3
移植干嘛?如果可能,删除以前的东西吧。重新开始学编程。
#4
如果你深陷于什么性能、空间的纠结里出不来,对你的应用程序(而是简单地一两条语句)进行测试,看看这个纠结值几毛钱,可以不可以不问自己“请问C#如何实现以上代码”的问题的情况下同样完成自己的任务、赢得用户,这就够了。
测试来说了算,不要搞理论。
测试来说了算,不要搞理论。
#5
Ok,删除以前的东西重新用C#编程,
那么C++实现的那个代码,
请问用C#如何实现?
谢谢!
#6
这不是理论,
这是实实在在、普普通通的C++代码,
老哥!
你没写过这方面的代码,
拜托你不要用“理论”一次来形容它好吗?
#7
看不出你链接指向的帖子与我这个问题的联系。
#8
非指针写法
Class _cmdTag
{
public byte cmd;
public byte cmd_type;
public byte active;
public static _cmdTag Convert(Byte[] b)
{
判断b
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
void SetCmdFrame(byte[] pBuf, byte cmd, byte cmd_type)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
pFrame.cmd = cmd;
pFrame.cmd_type = cmd_type;
pFrame.active = 0; //主动或被动
...
}
void IsCmdFrame(byte[] pBuf)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
if(pFrame.cmd == CMD_SEND_DATA)
{
...
}
...
}
Class _cmdTag
{
public byte cmd;
public byte cmd_type;
public byte active;
public static _cmdTag Convert(Byte[] b)
{
判断b
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
void SetCmdFrame(byte[] pBuf, byte cmd, byte cmd_type)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
pFrame.cmd = cmd;
pFrame.cmd_type = cmd_type;
pFrame.active = 0; //主动或被动
...
}
void IsCmdFrame(byte[] pBuf)
{
_cmdTag pFrame = _cmdTag.Convert(pBuf);
if(pFrame.cmd == CMD_SEND_DATA)
{
...
}
...
}
#9
谢谢您!
不过老哥,
请您先弄明白什么叫做C++的“位域”吧!
#10
C#当前版本不支持位域
#11
要那么严格的话,C#好像做不到
#12
凡是把下面代码:
//C++ code
struct _cmdTag
{
unsigned char cmd:4;
unsigned char cmd_type:3;
unsigned char active:1;
};
理解为:
struct _cmdTag
{
unsigned char cmd[4];
unsigned char cmd_type[3];
unsigned char active[1];
};
或者:
struct _cmdTag
{
unsigned char[4] cmd;
unsigned char[3] cmd_type;
unsigned char[1] active;
};
请,先弄明白C++的“位域”,
谢谢!
//C++ code
struct _cmdTag
{
unsigned char cmd:4;
unsigned char cmd_type:3;
unsigned char active:1;
};
理解为:
struct _cmdTag
{
unsigned char cmd[4];
unsigned char cmd_type[3];
unsigned char active[1];
};
或者:
struct _cmdTag
{
unsigned char[4] cmd;
unsigned char[3] cmd_type;
unsigned char[1] active;
};
请,先弄明白C++的“位域”,
谢谢!
#13
看来这个小问题,
竟然遇到大麻烦了,
老板让我们转到C#,
看来C#并不能完成C++所能完成的全部功能啊。
#14
从应用的层面来说,一个语言能够实现的功能,几乎都能够用其它任何一种合格的语言来实现,其区别只有编码效率和运行效率的区别。就像SP1234说的,不要纠结这些细节,用C#重写一次就行了
#15
帮你查到一篇,是这个
http://topic.csdn.net/t/20030531/22/1860471.html
http://topic.csdn.net/t/20030531/22/1860471.html
#16
微软不是号称C#无所不能吗,
能完成C++所有的功能吗?
晕,到底转向C#可以吗?
#17
我丝毫不像纠结于什么细节,
我就想知道C#该如何重写它,
仅此而已!
#18
“微软不是号称C#无所不能吗,”,没听说过啊。
#19
udp组包的时候用过,原来这个叫位域啊
上面这个帖子牛,想到枚举
上面这个帖子牛,想到枚举
#20
谢谢!那个帖子的问题与我这个问题有相似的地方,
但是它那是用C#的枚举解决问题,
但这是不行的,例如:
struct _cmdTag
{
unsigned int cmd:4;
unsigned int active:1;
unsigned int frame_len:27;
};
就没法解决,因为frame_len是表示27bit的整数值。
#21
用枚举不行,请看我的帖子。
#22
这些拿微软一些控件来写界面的所谓“程序员”,
真让人抓狂啊,
还怪别人搞些“理论的东西”!
#23
以前用c组过mac帧,的确比c#方便很多,后来再做都是用整形和字符串组byte,没想到什么好办法
#24
http://archive.cnblogs.com/a/1942446/
#25
脑筋不要这么死板好不好,c++有位域,c#就一定要支持?那要让你把C++的代码给改成perl的,你不是要抓狂了。
你那个结构用C#写成下面这样,浪费一点空间不就完了,active的类型也可以改成bool。移植程序嘛,灵活一点。要是什么都完全一样,就用不着移植了
struct _cmdTag
{
unsigned char cmd;
unsigned char cmd_type;
unsigned char active;
};
你那个结构用C#写成下面这样,浪费一点空间不就完了,active的类型也可以改成bool。移植程序嘛,灵活一点。要是什么都完全一样,就用不着移植了
struct _cmdTag
{
unsigned char cmd;
unsigned char cmd_type;
unsigned char active;
};
#26
朋友,你没有写过类似的东西,可能没法理解
例如
void compose(char* buffer)
{
//buffer 是需要out的数据帧 函数内组包
//ether头 结构体
ether_header* eh;
//arp头 结构体
arp_header* ah;
eh = (etherheader*)buffer;
ah = (arp_header*)(buffer+sizeof(ether_header)) ;
eh.dmac =...
...
ah.targetip = ...
这样,在数据帧的各部分结构体的数据赋值完毕之后,buffer也同时填充完毕了
也就是说,如果用了char,那么在buffer中就明显存在了问题,因为原来是1bit的数据你填充了8bit!!!
}
这个问题要从内存角度去理解,个人在C#还没有发现可以达到这种目的的方法,当然可能是我才疏学浅
#27
楼主啊,不管数据帧内各部分是什么,最后组包完毕总是byte的整数倍
所以如果没什么好办法的话,用char或者其他类型作为结构体的成员类型,敷值完毕以后自己计算byte
很傻,不过能做出来
C#有自己的优势,不过底层的东西,还是C比较方便
所以如果没什么好办法的话,用char或者其他类型作为结构体的成员类型,敷值完毕以后自己计算byte
很傻,不过能做出来
C#有自己的优势,不过底层的东西,还是C比较方便
#28
话说好久没写C了,貌似有些写错了,各位看官莫笑
#29
不知道这样行不
class Program
{
static void Main(string[] args)
{
CmdTag ct = new CmdTag(25);
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"],ct["active"]));
ct["cmd"] = 3;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
ct["cmd_type"] = 6;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
ct["active"] = 1;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct["cmd"], ct["cmd_type"], ct["active"]));
CmdTag ct1 = (CmdTag)3;
Console.WriteLine(string.Format("cmd:{0} cmdType:{1} active:{2}", ct1["cmd"], ct1["cmd_type"], ct1["active"]));
Console.ReadLine();
}
}
class CmdTag
{
private byte _v;
//构造函数
public CmdTag() { }
public CmdTag(byte v)
{
_v = v;
}
//强制运算符的重载,将byte转换为CmdTag类型
public static explicit operator CmdTag(byte b)
{
return new CmdTag(b);
}
//索引器
public byte this[string str]
{
//获取字段值
get
{
if (str == "cmd") return (byte)(_v >> 4);
if (str == "cmd_type") return (byte)((_v & 0xf) >> 1);
if (str == "active") return (byte)(_v & 0x01);
throw new Exception(string.Format("不存在字段:{0}", str));
}
//设置字段值
set
{
if (str == "cmd") _v = (byte)((_v&0xf)|(value<<4));
else if (str == "cmd_type") _v =(byte)((_v&0xf1)|(value<<1));
else if (str == "active") _v = (byte)((_v&0xfe)|value);
else throw new Exception(string.Format("不存在字段:{0}",str));
}
}
}
#30
抱歉有点错误
if (str == "cmd") _v = (byte)((_v&0xf)|(value<<4));
else if (str == "cmd_type") _v = (byte)((_v & 0xf1) | ((value << 1) & 0xe));
else if (str == "active") _v = (byte)((_v&0xfe)|(value&0x1));
else throw new Exception(string.Format("不存在字段:{0}",str));
#31
楼上那个写得很好了,我再班门弄斧一下,哈哈
struct _cmdTag
{
public byte b;
public byte cmd()
{
return (byte)(((byte)(b << 4)) >> 4);
}
public byte cmd_type()
{
return (byte)(((byte)(b << 1)) >> 5);
}
public byte active()
{
return ((byte)(b >> 7));
}
}
unsafe static void Main(string[] args)
{
byte* f = stackalloc byte[10];
*f = 248;
_cmdTag* d = (_cmdTag*)f;
Console.WriteLine(d->cmd());
Console.WriteLine(d->cmd_type());
Console.WriteLine(d->active());
Console.ReadLine();
}
struct _cmdTag
{
public byte b;
public byte cmd()
{
return (byte)(((byte)(b << 4)) >> 4);
}
public byte cmd_type()
{
return (byte)(((byte)(b << 1)) >> 5);
}
public byte active()
{
return ((byte)(b >> 7));
}
}
unsafe static void Main(string[] args)
{
byte* f = stackalloc byte[10];
*f = 248;
_cmdTag* d = (_cmdTag*)f;
Console.WriteLine(d->cmd());
Console.WriteLine(d->cmd_type());
Console.WriteLine(d->active());
Console.ReadLine();
}
#32
C#不能直接实现,自己做位运算吧。
#33
C#肯定不能直接提供你想要的这种功能,你需要像后面几位回复写的那样,写一些把结构体转换成字符流的代码。肯定要比C++麻烦,这是语言本身决定了的。还是那句话,要是把这段代码转换成perl,你怎么办?多想办法,多绕弯子嘛,移植的工作量就是在这些东西方面了
#34
#35
try like this
using System;
namespace BitfieldTest
{
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed class BitfieldLengthAttribute : Attribute
{
uint length;
public BitfieldLengthAttribute(uint length)
{
this.length = length;
}
public uint Length { get { return length; } }
}
static class PrimitiveConversion
{
public static long ToLong<T>(T t) where T : struct
{
long r = 0;
int offset = 0;
// For every field suitably attributed with a BitfieldLength
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
{
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
if (attrs.Length == 1)
{
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
// Calculate a bitmask of the desired length
long mask = 0;
for (int i = 0; i < fieldLength; i++)
mask |= 1 << i;
r |= ((UInt32)f.GetValue(t) & mask) << offset;
offset += (int)fieldLength;
}
}
return r;
}
}
struct PESHeader
{
[BitfieldLength(2)]
public uint reserved;
[BitfieldLength(2)]
public uint scrambling_control;
[BitfieldLength(1)]
public uint priority;
[BitfieldLength(1)]
public uint data_alignment_indicator;
[BitfieldLength(1)]
public uint copyright;
[BitfieldLength(1)]
public uint original_or_copy;
};
public class MainClass
{
public static void Main(string[] args)
{
PESHeader p = new PESHeader();
p.reserved = 3;
p.scrambling_control = 2;
p.data_alignment_indicator = 1;
long l = PrimitiveConversion.ToLong(p);
for (int i = 63; i >= 0; i--)
{
Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");
}
Console.WriteLine();
return;
}
}
}
#36
直接的没有。不过间接的方法还是很多的。
#37
你说得倒是好,
改下代码就行吗?
把所有设备的代码都改变吗?
那么请说服大家把TCP等等协议都改变吧!
#38
感觉绕了很大弯,
挺费劲的。
#39
谢谢您的鼎力帮助,
感觉费了挺大的劲儿,
费了九牛二虎之力,
效果还够呛,
看来用C#写底层代码,
还真的不行,
得给老板建议不要转向C#了。
#40
这样的贸然转型确实很危险,以LZ目前对C#的了解,即使转过来,项目或产品的质量也是无法保证的,尤其是涉及这种底层细节,需要有足够经验积累才可以。如果老板非要转的话,LZ可以建议先把一些简单、C#有优势的部分做移植
#41
看来界面部分可以先转到C#,
底层代码还是要用C++。
#42
谢谢!您的方法感觉比较可行,
由于我对C#了解有限,所以代码还需验证。
#43
总算听到了有哲理的话。
#44
算啦吧,不懂装懂,
见过巴掌大的天,
就以为自己的办法天下都通用。
#45
说什么“性能”、“空间”啊之类的话,
我问的问题与性能之类的东西有什么关系呢?
你以为这都是C++的人故意显示自己水平高,
故意造作使用位域吗?
不懂你就别跟着别人屁股后瞎嚷嚷了,
让人看得你的根基有多浅薄。
#46
真晕啊,
问了个位域问题,
硬是让一帮人说C++故意执拗于性能,
故意钻牛角之类显示自己理论多高的样子,
说白了,做应用软件的人,
很难理解底层为什么要这么做,
真是不做一行,不懂一行啊,
希望那些没有做过底层的,
不要再以此来讥讽了,
做C++的并不是为显摆才让代码那样子,
我也知道了C#的局限,
所以转入C#也会深重考虑了。
问了个位域问题,
硬是让一帮人说C++故意执拗于性能,
故意钻牛角之类显示自己理论多高的样子,
说白了,做应用软件的人,
很难理解底层为什么要这么做,
真是不做一行,不懂一行啊,
希望那些没有做过底层的,
不要再以此来讥讽了,
做C++的并不是为显摆才让代码那样子,
我也知道了C#的局限,
所以转入C#也会深重考虑了。
#47
_cmdTag c = new _cmdTag();
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
c.cmd = b[0];
c.cmd_type = b[1];
c.active = b[2];
return c;
}
};
#48
好難懂,在學習中
#49
各位仙人非同一般//我也喜欢还是喜欢C
#50
To ChinaOS
非托管 转 托管的时候并不一定要把代码全部重写,也可以试着将非托管的部分封装成dll,给托管代码调用
像bitfield 及 union等最好能通过接口封装掉,不是说C#不能调,而是降低调用的麻烦程度,凡事有个度,具体事情具体衡量。
PS:某些人回答问题最好能看清楚别人问的问题是什么才回答,而不是一上来就否定人家,给出的建议也没什么建树,不知所云,不止在一个帖子里看到这样的回答,忍不住多嘴一句。
非托管 转 托管的时候并不一定要把代码全部重写,也可以试着将非托管的部分封装成dll,给托管代码调用
像bitfield 及 union等最好能通过接口封装掉,不是说C#不能调,而是降低调用的麻烦程度,凡事有个度,具体事情具体衡量。
PS:某些人回答问题最好能看清楚别人问的问题是什么才回答,而不是一上来就否定人家,给出的建议也没什么建树,不知所云,不止在一个帖子里看到这样的回答,忍不住多嘴一句。