Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将curl结果中的字节组解释为其他数据类型的方法_C++_C_Curl - Fatal编程技术网

C++ 将curl结果中的字节组解释为其他数据类型的方法

C++ 将curl结果中的字节组解释为其他数据类型的方法,c++,c,curl,C++,C,Curl,我正在尝试编写一个程序,它将使用curl查询URL并检索一串字节。返回的数据需要解释为各种数据类型;后跟序列结构的int curl写回函数必须具有以下原型: size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata); 我见过各种例子,其中返回的数据以字符或字符串对象的形式直接存储在内存中的缓冲区中 如果我有一个字符数组,那么我知道我可以用如下代码将它的一部分解释为一个结构: struct mystru

我正在尝试编写一个程序,它将使用curl查询URL并检索一串字节。返回的数据需要解释为各种数据类型;后跟序列结构的int

curl写回函数必须具有以下原型:

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
我见过各种例子,其中返回的数据以字符或字符串对象的形式直接存储在内存中的缓冲区中

如果我有一个字符数组,那么我知道我可以用如下代码将它的一部分解释为一个结构:

struct mystruct {
    //define struct
};

char *buffer;
//push some data into the buffer
char *read_position;
read_position = buffer + 5;
test = (mystruct *)buffer;

我有两个相关的问题。首先,有没有更好的方法使用curl检索二进制数据并将其推入结构,而不是将其作为字符直接读入内存。其次,如果作为一个字符缓冲区读取内存的方法,我的代码是否是一种明智的方式来解释内存块作为不同的数据类型?

解释原始结构时需要考虑的事情,特别是在网络上:

  • 数据类型的大小
  • 数据类型的endianness
  • 结构填充
无论使用哪种编译器,都应该在结构中使用大小正确的数据类型。这意味着对于整数,应该使用

至于endian,您需要知道数据是以big-endian还是little-endian的形式到达的。我喜欢明确地说:

template< class T >
const char * ReadLittleEndian32( const char *buf, T & val )
{
    static_assert( sizeof(T) == 4 );
    val = T(buf[0]) | T(buf[1]) << 8 | T(buf[2]) << 16 | T(buf[3]) << 24;
    return buf + sizeof(T);
}

template< class T >
const char * ReadBigEndian32( const char *buf, T & val )
{
    static_assert( sizeof(T) == 4 );
    val = T(buf[0]) << 24 | T(buf[1]) << 16 | T(buf[2]) << 8 | T(buf[3]);
    return buf + sizeof(T);
}

//etc...
请注意,模板处理数据类型中的符号和其他内容,因此我们最终只关心大小。还要记住,诸如
float
double
之类的数据类型已经具有固有的尾端性,不应进行翻译——它们可以逐字读取:

const char * ReadDouble( const char * buf, double & val )
{
    val = *(double*)buf;
    return buf + sizeof(double);
}

我对你的答案投了更高的票,因为它非常有用,但我没有接受它,因为它没有解决我问题的卷曲部分。另外,你的回答表明我的代码片段(直接复制内存)非常幼稚,我认为你应该在回答中明确地说出来。这很公平。您应该意识到,如果您有自定义的二进制数据,CURL并不关心。这只是二进制数据。您可以使用CURL提供的任何方法来处理这些数据,并根据需要读取数据。在那一点上与旋度无关。这可以归结为通过网络处理二进制数据的常见做法,我想我已经讨论过了。我假设您自己在服务器端序列化这些数据,也在客户端反序列化这些数据。我只是觉得效率低下。curl调用一个写回函数,并将一个字符指针和读取的字节数一起传递给它,这意味着数据已经在内存中。简单地将这些数据从内存的一部分复制到另一部分似乎是不必要的。我想知道是否有更好的方法来处理curl返回的数据。是的,我正在连接的远端用PHP序列化。谢谢你的帮助。我没有在代码中集成CURL的直接经验,但我怀疑它不会总是在一个回调中提供完整的二进制数据。I/O回调通常具有固定的缓冲区大小,并向您提供一些达到该缓冲区大小的数据,在连续回调中返回剩余的数据。在这种情况下,您唯一的选择就是将数据复制到某个地方,这绝对是一件正常的事情。是的,curl就是这样工作的,多次回调。我知道库中有一些对象包装器,我想知道是否可以将返回的数据视为流,让提取操作符根据需要填充不同的数据类型。我看到您在
C
标记中重新编辑了。请注意,没有这样的语言,如“C/C++”。正如我在编辑中所说的,我不习惯使用任何一种语言,也不乐意考虑其中的解决方案。我更熟悉C++,希望有一些有用的抽象,比如流,这可能是有用的。
const char * ReadDouble( const char * buf, double & val )
{
    val = *(double*)buf;
    return buf + sizeof(double);
}