我目前正在为现有网络远程开发C ++ 11库 接口控制文档(ICD)中描述的控制接口。
该接口基于TCP / IPv4并使用网络字节顺序(又名 Big 端)。
要求:图书馆应开发跨平台。
注意:我想使用预处理器开发不带(ab)的解决方案。
经过对WWW的简短研究,我发现Boost.Endian解决了这个问题 与多字节数据类型的endianess相关的问题。我的方法是 如下:
os.write(reinterpret_cast<char const *>(&kData), sizeof(kData))
。std::basic_ostream
转换为std::vector<std::uint8_t>
。std::vector<std::uint8_t>
发送Word | Bit(s) | Name
-----|--------|----------
10 | 0-2 | a
10 | 3 | b
10 | 4 | c
10 | 5 | d
10 | 6 | e
10 | 7 | RESERVED
11 | 16 | f
。到目前为止一切顺利。一切似乎按预期工作,解决方案应该是 平台独立。
现在是棘手的部分:ICD描述了由多个组成的消息 单词和一个单词由8位组成。一条消息可以包含多个字段和一个 字段不必是字节对齐的,这意味着一个字可以包含 多个领域。
示例:考虑以下消息格式(消息正文开头于 10):
boost::dynamic_bitset
依旧......
所以现在我需要一个能够建模和序列化基于位的接口的解决方案。
到目前为止,我已经研究过以下方法:
boost::dynamic_bitset
不是跨平台的(取决于编译器)。// Using a arithmetic type from the `boost::endian` namespace does not work.
using Byte = std::uint8_t;
using BitSet = boost::dynamic_bitset<Byte>;
BitSet bitSetForA{3, 1};
BitSet bitSetForB{1};
// [...]
BitSet bitSetForF{16, 0x400}; // 1024
的以下示例没有
为我的方案工作:代码:
00 04
因此,上面示例中的1024始终序列化为04 00
而不是。{
<?php require_once '../db_con.php';
if(!empty($_GET['cat_id'])){
$doc = intval($_GET['cat_id']);
try{
$results = $dbh->prepare('SELECT * FROM cat_list WHERE cat_id = ?');
$results->bindParam(1, $doc);
$results->execute();
} catch(Exception $e) {
echo $e->getMessage();
die();
}
$doc = $results->fetch(PDO::FETCH_ASSOC);
if($doc == FALSE){
echo '<div class="container">';
echo "<img src='../img/404.jpg' style='margin: 40px auto; display: block;' />";
echo "<h1 style='margin: 40px auto; display: block; text-align: center;' />Oh Crumbs! You upset the bubba!</h1>";
echo '<a href="userList.php" style="margin: 40px auto; display: block; text-align: center;">Get me outta here!</a>';
echo'</div>';
die();
}
}
?>
在我的机器上。
我真的不知道什么是最实用的方法来解决我的问题。 也许你可以引导我走向正确的方向。
总之,我确实需要一个配方来实现现有的网络接口定义位 字段与平台无关的方式相对于本机字节顺序 已编译库的机器。
答案 0 :(得分:0)
最近有人向我指出nice article about endianness,我从中获取了灵感。
std::bitset
有一个to_ulong
方法,可以用来返回位域的整数表示(与endian无关),以下代码将以正确的顺序打印输出:
#include <iostream>
#include <iomanip>
#include <bitset>
int main()
{
std::bitset<16> flags;
flags[10] = true;
unsigned long rawflags = flags.to_ulong();
std::cout << std::setfill('0') << std::setw(2) << std::hex
<< (rawflags & 0x0FF) // little byte in the beginning
<< std::setw(2)
<< ((rawflags>>8) & 0x0FF) // big byte in the end
<< std::endl;
}
请注意,在这种情况下,使用位字段的解决方案不会很容易,因为这些位也会在小端机器上交换!
e.g。在这样的结构中:
struct bits {
unsigned char first_bit:1;
unsigned char rest:7;
};
union {
bits b;
unsigned char raw;
};
将b.fist_bit设置为1将导致原始值为1或128,具体取决于字节顺序!
HTH