如何将char *附加到void *的末尾?

时间:2017-02-21 07:10:00

标签: c++ pointers append libcurl

假设我们已经定义了一个char *如下:

char *x;

我们有类似的功能:

void append(void *y, char *z);

此函数将其第二个参数(指针 z 指向的位置)附加到指针 y 指向其开头的字符串末尾。我被限制为第一个参数为 void * 的原因是我需要覆盖libcurl函数:

size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata);

每次调用header_callback函数时,我都需要将缓冲区附加到userdata的末尾。 userdata指针指向字符串的开头。

4 个答案:

答案 0 :(得分:1)

根据您链接的文档, userdata 是先前提供给 CURLOPT_HEADERDATA 的指针。这样的事可能适合你。

size_t header_callback(char *buffer, size_t size, size_t nitems, vector<string> *userdata)
{
    userdata->push_back(string(buffer, size*nitems));
    return size*nitems;
}

//...
vector<string> headers;
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headers);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
//...

答案 1 :(得分:0)

无法实现

void append(void *y, char *z);

以这种方式可以附加一个非空终止的字符序列。

给回调的char *buffer是非空终止的。

此外,您可以在调用append之前将void指针转换为回调中缓冲区的正确类型。这必须最终完成,因为你无法附加任何内容。

你几乎不需要外部功能,因为追加是非常微不足道的。假设您的void*指向std::string

auto bytes = size * nitems;
auto str = (std::string*)userdata;
str->append(buffer, bytes);

答案 2 :(得分:0)

要将数据附加到缓冲区,应该定义这些内容:

  • 允许的目标缓冲区大小
  • 目标缓冲区中存在的缓冲区中的数据量
  • 要复制到目标缓冲区的数据量

在C realloc()中可以用来创建内容为旧的缓冲区...可能会也可能不会改变缓冲区的位置。在C ++中,有一些新的运算符可以实现类似的操作。

如果我们假设存储的数据是严格以空字符结尾的字符串(但即使没有指定!),那么第二和第三是已知的 - 缓冲区的大小未知,append()是缓冲区的大小。因此,功能

void append(void *y, char *z);

看起来要么不适合任务,要么非常不安全且可能定义不明确,除非void y实际上是某个结构或类(但是将其作为void 传递)

您没有提供它的实现或描述。看起来应该是相当有限的一个。我们应该预先分配一个适当大小的缓冲区,并确保append()不会在其边界之外运行。它无法重新分配目标缓冲区,因此受分配的内存限制。要实际重新分配目标缓冲区附加,可以使用void **yvoid &* y作为形式参数(realloc()可以更改指针, 从旧缓冲区复制数据到新的缓冲区)

这造成了一个架构问题 - 缓冲区的所有权。如果我们传递我们控制的缓冲区,我们可以正确分配它并将其传递给append()或将所有权传递给append(),以便重新分配它。如果我们不这样做,我们必须创建一个时间缓冲区......但是之后我们可以使用那个时间缓冲区吗?

除非您使用自定义标头写入功能,否则这一点没有实际意义。用户数据指针是CURLOPT_HEADERDATA,它是指向有效FILE的指针,你应该_fwrite()数据...或者,如果你正在实现CURLOPT_WRITEFUNCTION和CURLOPT_READFUNCTION回调,那么该指针可以由回调设计者自行决定使用,指向一些有用数据容器的指针(libcurl使用fwrite作为默认回调)。

答案 3 :(得分:-1)

您的问题更多地是指C(而非C ++)方法。然后你需要以下内容:

  1. 知道y的大小
  2. 将y重新分配为大小为+ 1
  3. memcpy / memmove y到新的地方
  4. 将新缓冲区的最后一个字节设置为z
  5. 向用户返回指针和新缓冲区的大小
  6. 释放旧缓冲区y(取决于需要)。
  7. 在C ++ hovewer中你需要使用一些像std :: vector这样的容器,它允许你附加一个字节。