要使用 zlib 压缩/解压缩数据,首先我需要设置一个名为 z_stream
的结构.
z_stream
有两个非常量指针叫做 next_in
和 next_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/