npv1例子的疑惑
大家好 我刚开始学ACE 有个问题想请教一下在第4章的loggingserver例子里
The Logging Service Message Framing Protocol 里面规定byteorder是4个字节
但是为什么cdr >> ACE_InputCDR::to_boolean (byte_order) 读的时候却是按bool来读的?难道ACE里bool占4个字节吗?
而后面直接读length, 这样没有问题吗,为什么指针不要跳3个字节?前面读byteorder的时候只读了1个字节阿?
24 ACE_CDR::ULong length;
25 cdr>>length;
请大家帮帮我 谢谢 其实这句代码上面的注释,已经说明了,是先读取4个字节的char,再用to_boolean的方法,转换成bool类型来操作。至于传递的数据里面不用bool,是因为需要数据对齐的原因。
所以后面直接读length,不会有问题的。你可以调试一下代码就明白了。 还是没弄明白 debug进去看了下
cdr >> ACE_InputCDR::to_boolean (byte_order)确实只读一个字节阿
并没有看到先读4个char
server:
ACE_InputCDR cdr (payload);
// Extract the byte-order and use helper methods to
// disambiguate octet, booleans, and chars.
ACE_CDR::Boolean byte_order;
cdr >> ACE_InputCDR::to_boolean (byte_order);
client:
ACE_OutputCDR header (ACE_CDR::MAX_ALIGNMENT + 8);
header << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER);
// Store the size of the payload that follows
header << ACE_CDR::ULong (length); 我看的英文的 问题已经解决了
我深入debug了 ace在写和读数据之前对齐数据
假设内存起始地址为0,你要写的数据为 BYTE DWORD BYTE WORD BYTE DWORD
那么实际数据的存放位置为 0 4 9 10 12 16
也就是说你所存储的数据的地址会被ACE修改为数据类型大小的倍数
也就是说bytecode占一个字节,跳过3个字节,然后存放length, 总共还是占8个字节
书上并没有讲清楚,而且制定传输的数据大小的时候用了这样的写法
ACE_OutputCDR header (ACE_CDR::MAX_ALIGNMENT + 8);
header << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER);
header << ACE_CDR::ULong (length);
iovec iov;
iov.iov_base = header.begin ()->rd_ptr ();
iov.iov_len= 8;
很容易让人误解,以为bytecode和length各占4个字节,其实bytecode只占1个字节,中间的字节都跳过了
我觉得最好写成 iov.iov_len= header.totoal_length(); 更容易理解些
大家看例子的时候没有发现这个问题吗?希望我这个发现对大家会有帮助 1:to_boolean 这里确实只读了1个字节
===============
to_boolean 是类ACE_InputCDR的内嵌的一个结构类型。
struct to_boolean
{
ACE_CDR::Boolean& ref;
to_boolean(ACE_CDR::Boolean& in):ref(in){};
};
cdr >> ACE_InputCDR::to_boolean( in);//右边构造了一个匿名变量,其类型为ACE_InputCDR::to_boolean,该变量的成员ref是in的引用。
就是
cdr::operator >>(ACE_InputCDR::to_boolean(in));
或者说可以更啰嗦地写为:
ACE_InputCDR::to_boolean var(in);
cdr >> var;
2:接下来读ULONG
===================
ACE_CDR::Boolean
ACE_InputCDR::read_4 (ACE_CDR::ULong *x)
{
char *buf;
if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0) //在读ULONG的4个字节前调用了adjust
{
#if !defined (ACE_DISABLE_SWAP_ON_READ)
if (!this->do_byte_swap_)
*x = *reinterpret_cast<ACE_CDR::ULong*> (buf);
else
ACE_CDR::swap_4 (buf, reinterpret_cast<char*> (x));
#else
*x = *reinterpret_cast<ACE_CDR::ULong*> (buf);
#endif /* ACE_DISABLE_SWAP_ON_READ */
return true;
}
this->good_bit_ = false;
return false;
}
CDR_BASE.h里定义了枚举 LONG_SIZE = 4
adjust做了什么?
ACE_INLINE int
ACE_InputCDR::adjust (size_t size,
size_t align,
char*& buf)
{
#if !defined (ACE_LACKS_CDR_ALIGNMENT) //如果config.h里没有定义此宏,则需要调整读指针按align=4对齐
buf = ACE_ptr_align_binary (this->rd_ptr (), align);
#else
buf = this->rd_ptr (); //如果config.h里定义了此宏,则不需要调整读指针
#endif /* ACE_LACKS_CDR_ALIGNMENT */
char *end = buf + size;
if (end <= this->wr_ptr ())
{
this->start_.rd_ptr (end);
return 0;
}
this->good_bit_ = false;
return -1;
#if defined (ACE_LACKS_CDR_ALIGNMENT)
ACE_UNUSED_ARG (align);
#endif /* ACE_LACKS_CDR_ALIGNMENT */
}
ACE_ptr_align_binary 是如何调整读指针的?
请看这里,调整后读指针的地址按alignment对齐!
OS_Memory.h:
#define ACE_align_binary(ptr, alignment) \
((ptr + ((ptrdiff_t)((alignment)-1))) & (~((ptrdiff_t)((alignment)-1))))
/// Return the next address aligned to a required boundary
#define ACE_ptr_align_binary(ptr, alignment) \
((char *) ACE_align_binary (((ptrdiff_t) (ptr)), (alignment)))
结论:
===
1:读ACE_CDR::Boolean时:确实只读了一个字节,读完后没有移动指针至ULONG的起始处。
2:读ACE_CDR::ULONG时:如没有定义宏ACE_LACKS_CDR_ALIGNMENT,读指针先向后移动至按4字节对齐,再读ULONG的4个字节。
[ 本帖最后由 bodyguard 于 2008-7-30 00:25 编辑 ]
页:
[1]