找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4050|回复: 4

npv1例子的疑惑

[复制链接]
发表于 2008-1-14 21:09:39 | 显示全部楼层 |阅读模式
大家好 我刚开始学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;
请大家帮帮我 谢谢
 楼主| 发表于 2008-1-14 21:09:51 | 显示全部楼层
其实这句代码上面的注释,已经说明了,是先读取4个字节的char,再用to_boolean的方法,转换成bool类型来操作。至于传递的数据里面不用bool,是因为需要数据对齐的原因。
所以后面直接读length,不会有问题的。你可以调试一下代码就明白了。
 楼主| 发表于 2008-1-14 21:10:04 | 显示全部楼层
还是没弄明白 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);
 楼主| 发表于 2008-1-14 21:10:28 | 显示全部楼层
我看的英文的 问题已经解决了

我深入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[2];
    iov[0].iov_base = header.begin ()->rd_ptr ();
    iov[0].iov_len  = 8;

很容易让人误解,以为bytecode和length各占4个字节,其实bytecode只占1个字节,中间的字节都跳过了

我觉得最好写成 iov[0].iov_len  = header.totoal_length(); 更容易理解些

大家看例子的时候没有发现这个问题吗?希望我这个发现对大家会有帮助
发表于 2008-7-29 22:08:41 | 显示全部楼层
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 编辑 ]
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-23 17:24 , Processed in 0.019146 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表