- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在研究使用 boost::archive 的应用程序中从非标准字符串到标准字符串的端口。非标准字符串具有以非侵入式样式定义的(反)序列化,如下例所示。序列化和反序列化按预期工作,但是当移植的应用程序收到一条旧消息时,它会因分配错误而崩溃。这是由于在字符串大小之前插入了 5 个字节(全为零)造成的。
是什么导致插入这 5 个额外的字节?这是某种魔法标记吗?
例子:
#include <iostream>
#include <string>
#include <sstream>
#include <boost/serialization/split_free.hpp>
#include <boost/archive/binary_oarchive.hpp>
struct own_string { // simplified custom string class
std::string content;
};
namespace boost
{
namespace serialization
{
template<class Archive>
inline void save(
Archive & ar,
const own_string & t,
const unsigned int /* file_version */)
{
size_t size = t.content.size();
ar << size;
ar.save_binary(&t.content[0], size);
}
template<class Archive>
inline void load(
Archive & ar,
own_string & t,
const unsigned int /* file_version */)
{
size_t size;
ar >> size;
t.content.resize(size);
ar.load_binary(&t.content[0], size);
}
// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive>
inline void serialize(
Archive & ar,
own_string & t,
const unsigned int file_version)
{
boost::serialization::split_free(ar, t, file_version);
}
} // namespace serialization
} // namespace boost
std::string string_to_hex(const std::string& input)
{
static const char* const lut = "0123456789ABCDEF";
size_t len = input.length();
std::string output;
output.reserve(2 * len);
for (size_t i = 0; i < len; ++i)
{
const unsigned char c = input[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
return output;
}
void test_normal_string()
{
std::stringstream ss;
boost::archive::binary_oarchive ar{ss};
std::string test = "";
std::cout << string_to_hex(ss.str()) << std::endl;
ar << test;
//adds 00 00 00 00 00 00 00 00
std::cout << string_to_hex(ss.str()) << std::endl;
}
void test_own_string()
{
std::stringstream ss;
boost::archive::binary_oarchive ar{ss};
std::string test = "";
own_string otest{test};
std::cout << string_to_hex(ss.str()) << std::endl;
ar << otest;
//adds 00 00 00 00 00 00 00 00 00 00 00 00 00
std::cout << string_to_hex(ss.str()) << std::endl;
}
int main()
{
test_normal_string();
test_own_string();
}
最佳答案
因此,您希望将先前序列化的 own_string
反序列化为 std::string
。
来自 boost(1.65.1) doc :
By default, for each class serialized, class information is written to the archive. This information includes version number, implementation level and tracking behavior. This is necessary so that the archive can be correctly deserialized even if a subsequent version of the program changes some of the current trait values for a class. The space overhead for this data is minimal. There is a little bit of runtime overhead since each class has to be checked to see if it has already had its class information included in the archive. In some cases, even this might be considered too much. This extra overhead can be eliminated by setting the implementation level class trait to: boost::serialization::object_serializable.
现在,可能(*)这是标准类的默认值。事实上,添加
BOOST_CLASS_IMPLEMENTATION(own_string, boost::serialization::object_serializable)
在全局范围内使 test_X_string 结果相同字节。这应该可以解释观察到的额外字节差异。
也就是说,我没有找到关于标准类序列化特征的任何具体保证(其他人可能比我更了解)。
(*) 实际上是 section about portability of traits settings提到:
Another way to avoid this problem is to assign serialization traits to all specializations of the template my_wrapper for all primitive types so that class information is never saved. This is what has been done for our implementation of serializations for STL collections
因此这可能会给您足够的信心,让您相信标准集合(因此包括 std::string)在这种情况下会给出相同的字节。
关于c++ - 为什么非侵入式序列化会添加 5 字节零前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47608776/
发布以下查询时,出现错误响应 {"error":{"root_cause":[{"type":"parsing_exception","reason":"[prefix] query does not
我对 Python 和 Django 真的很陌生......我想做的是: 在 Mac OS 10.6.8 上安装 Python 2.7 安装 pip 安装 Django 安装 virtualenvwr
前缀表达式 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前。 例如: ( 3 + 4 ) × 5 − 6 (3+4)×5-6(3+4)×5−6 对应的前缀表达式就是 - × + 3 4 5 6
如何在Intel C编译器中定义俄语字符串? 在MSVS 2008中,我这样做: _wsetlocale(LC_ALL, L"Russian"); wprintf(L"текст"); 而且有效。 在
这是我到目前为止所得到的: SPECS = $(shell find spec -iname "*_spec.js") spec: @NODE_ENV=test \ @NODE_PAT
我看到了下面的前缀::它代表什么? :abc 是一个关键字,但是 ::abc 是什么? 谢谢,穆尔塔扎 最佳答案 假设当前命名空间是my.app。然后, ::x 是 :my.app/x 的阅读器简写,
我为我的 discord 创建了一个建议功能,用户可以说 +suggest(建议),它会自动发布到另一个 channel 。 有些事情我需要帮助: 将“建议由用户制作”放入标题中,而不是在单独的行中。
#include int main() { int a=1; printf("%d",(++a)++); return 0; } 此代码出现错误 error: invalid lvalue in
我在使用前缀和后缀运算符对数字执行减法时遇到了一个小问题。这是我的程序: public class postfixprefix { public static void main (Strin
当我在 Android native 浏览器中运行 HTML5 兼容性测试时,它会看到 IndexedDB 支持标记为“Prefixed”,而在 Chrome 和其他浏览器中则标记为“Yes”。我知道
我试过重载运算符--前缀,但我有错误,有人帮忙吗? #include #include "Circulo.h" using namespace std; int main() { //par
我正在尝试在我正在制作的这个论坛上创建一个引用功能,当我按下引用时,我只需用 Markdown 填充 textarea ,但唯一的事情是我需要在每行的 markdown 前面加上 > 前缀,这样它就是
friend 之间打赌。sum 变量定义为全局变量。我们有 2 个线程在循环 1..100 上运行并在每个循环中将 sum 递增 1。 打印什么?“和=”? int sum = 0; void fun
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Post Increment and Pre Increment concept? 谁能明确解释前缀增量与后
从模板类继承时,我需要在派生类中访问的所有基类成员前面加上this: template struct X{ int foo; void bar(); }; template struct
据我所知,在 C++ 中,在同一类的函数成员中调用另一个成员函数不需要“this”前缀,因为它是隐式的。但是,在使用函数指针的特定情况下,编译器需要它。仅当我通过 func 指针为调用包含“this”
例如,考虑以下名称冲突的地方 nest1 : template class nest1 {}; class cls { public: template class nest1 {};
我无法理解下面一段特定代码的逻辑。 int i[] = { 21, 4, -17, 45 }; int* i_ptr = i; std::cout << (*i_ptr)++ << std::endl
有人能给我指出正确的方向吗,我目前有一个可搜索的数据库,但遇到了按标题搜索的问题。 如果标题以“The”开头,那么显然标题将位于“T”部分,避免搜索“The”的好方法是什么?我应该连接两个字段来显示标
我在 2 小时前创建了一个新项目。以与我的旧(不同)项目相同的方式配置它,一切正常。 在我的 podfile 中我有: pod 'CocoaLumberjack', '2.0.0-rc2' 如果我在
我是一名优秀的程序员,十分优秀!