繁体   English   中英

从C / C ++获取指向msgpack数组中元素的指针和长度

[英]Get pointer to and length of element in msgpack array from C/C++

我有一些数据使用C / C ++ API与msgpack打包在一起,如下所示:

msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> pk(&sbuf);

int var1 = 10;
std::string var2 = "test";
double var3 = 3.14159; // could be any type

pk.pack_array(3);
pk.pack(var1);
pk.pack(var2);
pk.pack(var3);

稍后,我需要解压缩该数组,但是需要直接访问第三个元素,以便可以持久保存到file / db / redis / memcached / etc。 虽然数组的前两个元素是固定类型,但第三个元素可以是msgpack可接受的任何类型(int,字符串,向量,映射等)。

size_t off = 0;
msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.len(), off);
msgpack::object obj = result.get();

int var1;
obj.via.array.ptr[0].convert(&var1);

std::string var2;
obj.via.array.ptr[1].convert(&var2);

// now here I want to get a pointer & len to the 3rd item so I can persist
// this value that is already msgpack'd.

const char* dataptr = reinterpret_cast<const char*>(&obj.via.array.ptr[2]);
// now what is the length of the data pointed to by dataptr?

可能如上所述,我可以在obj.via.array.ptr [2]上执行reinterpret_cast,但是在二进制数据或msgpack的结构的情况下,简单的strlen()不会得到长度和无法看到从何处获得物品的长度。 我知道许多类型中都有一个size变量,但是当该项目是数组或映射时,我认为这是不正确的。

这是msgpack-c的内存模型: https : //github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#memory-management

我知道许多类型中都有一个size变量,但是当该项目是数组或映射时,我认为这是不正确的。

真正。 obj已被解压缩。 它不适合持久。 我认为直接存储msgpack格式的二进制数据是更好的方法。 首先,将msgpack分隔为前两个和第三个。 然后,将前两个打包成一个数组。 最后,只需打包第三个值。 那是包装过程。

    pk.pack_array(2); // for the first two
    pk.pack(var1);
    pk.pack(var2);
    pk.pack(var3);    // for the thrid one

解压缩时,请解压缩具有偏移量的前两个数据。

    // Unpacking
    size_t off = 0;
    msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.size(), off);
    // off has been set

打开包装后,已设置偏移量。 这样就可以获取第三个数据的起点。 然后,存储msgpack格式的二进制数据。

    std::string store; // file/db/redis/memcached/etc
    std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));

那是存储过程。

从存储中获取msgpack格式的二进制数据时,请解压缩它们。

这是一个完整的代码示例:

#include <msgpack.hpp>

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    msgpack::sbuffer sbuf;
    msgpack::packer<msgpack::sbuffer> pk(&sbuf);

    int var1 = 10;
    std::string var2 = "test";
    double var3 = 3.14159; // could be any type

    // Separate the data into the two msgpacks
    pk.pack_array(2); // for the first two
    pk.pack(var1);
    pk.pack(var2);
    pk.pack(var3);    // for the thrid one

    // Unpacking
    size_t off = 0;
    msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.size(), off);
    msgpack::object obj = result.get();

    auto converted = obj.as<std::tuple<int, std::string>>();
    std::cout << std::get<0>(converted) << std::endl;
    std::cout << std::get<1>(converted) << std::endl;

    // Storing the thrid one
    std::cout << "off: " << off << std::endl;
    std::string store; // file/db/redis/memcached/etc
    std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));

    {
        // Unpack the thrid one from store
        msgpack::unpacked result = msgpack::unpack(store.data(), store.size());
        msgpack::object obj = result.get();
        if (obj.type == msgpack::type::FLOAT) {
            auto f = obj.as<float>();
            std::cout << f << std::endl;
        }
    }
}

您可以在此处检查上面代码的行为: http : //melpon.org/wandbox/permlink/uFfRGKQLqnIIiDrv

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM