c++ - 将 zlib 与 const 数据一起使用

标签 c++ casting constants zlib stdvector

要使用 zlib 压缩/解压缩数据,首先我需要设置一个名为 z_stream 的结构. z_stream有两个非常量指针叫做 next_innext_out .

如果我想做这样的功能:

void ungzip(std::vector<unsigned char>& dst,const std::vector<unsigned char>& src)
{
  z_stream strm;
  // more code
}

和其他类似的

void gzip  (std::vector<unsigned char>& dst,const std::vector<unsigned char>& src);

我该怎么办?

在本地复制 src std::vector<unsigned char>

std::vector<unsigned char> tmp(src);

并像这样将其用作源或设置指针,strm.next_in = const_cast<char*>(&src[0])

zlib 是否保留输入数据?

最佳答案

可能最干净的方法是在编译时只定义 ZLIB_CONST,这样输入指针就被定义为 const unsigned char *

但是请注意,简单地放弃常量性确实可行(如果指向的字符实际上不是常量,这是合法的)。 代码应该是:

strm.next_in = (unsigned char *)&src[0];

或者更丑陋的 const_cast 变体,如果你喜欢那种东西的话。

请注意,zlib 中的默认设置是不定义 ZLIB_CONST 的,如果您想使用预编译的 zlib 二进制文件,则转换解决方案是最好的选择。仅当您也使用相同的定义(1) 自己编译库时,您才应该选择ZLIB_CONST 解决方案。


(1) 为编译器提供具有不同语义含义的 header 是一个坏主意 - 并且正式违反 C++ 标准规则 - 并且它可能 - 至少在理论上 - 会产生可移植性问题。

对于 X86 架构,情况可能并非如此,使用或不使用 ZLIB_CONST 编译的库将以完全相同的字节结束;但是也有不同的架构。

例如,我一直在使用 CPU,其中有不同的指针寄存器用于不同的对齐方式。在那个 CPU 读取中,一个不是整数或 4 的地址的整数是生成硬件陷阱的错误(此外,当时令我惊讶的是,即使只是将指针分配给一个非对齐的指针,也会触发错误地址,即使该未对齐的地址从未用于读取或写入)。

对于那个编译器我没有检查(我只在高级软件上工作)但是如果系统 ABI 指定函数 void foo(char *) 我不会感到惊讶和 void bar(int *) 必须在不同的寄存器中接收参数。

更重要的是,我从未使用过但我可以想象可能存在某些寄存器(我们将其命名为 RW0)可用于读取/写入操作和其他寄存器的 CPU 或 VM (例如 R0)只能用于读取。 使用这样的体系结构,ABI 可以指定 const char * 类型的第一个参数必须在 R0 中传递,并且 char * 类型的第一个参数必须传递> 必须改为在 RW0 中传递。

如果是这种情况,使用函数 void foo(char *p){...} 编译库,然后使用 as declaration void foo(const char *p); 实际上最终会在错误的寄存器中传递地址!

关于c++ - 将 zlib 与 const 数据一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44958875/

相关文章:

c++ - 如何让 VS2013 停止生成对 __dtol3、__dtoui3 和其他整数类型转换函数的调用?

java - android.support.v7.widget.AppCompatTextView 无法转换为 android.widget.RelativeLayout

CUDA 代码中的常量内存使用

c++ - 二进制字面量?

c++ - 我可以对 vector 进行排序以匹配 unordered_map 的排序吗?

c++ - VS2010、DirectX 和 Intellisense 问题

c++ - 将指向局部变量的指针传递给另一个进程有时有效,但有时无效

delphi - delphi中有这个VB代码的相关语法吗?

c++ - c++中关于const成员函数的问题

Objective-C 重新定义类