我有一个(void*)
缓冲区需要转换为std::vector<unsigned char>
才能传递它。不幸的是,我的C ++演员技能有点弱。有什么建议吗?
答案 0 :(得分:25)
您需要缓冲区的长度。一旦你这样做,我们就可以做到:
unsigned char *charBuf = (unsigned char*)voidBuf;
/* create a vector by copying out the contents of charBuf */
std::vector<unsigned char> v(charBuf, charBuf + len);
好的,评论让我开始讨论为什么我没有使用reinterpret_cast
:
在C ++中,C风格的强制转换是一种便利功能 - 它要求编译器在可用的强制转换操作符集上选择最安全,最便携的转换形式。
reinterpret_cast
是实现定义的,应该永远是你心中的最后一件事(并且当你必须故意做一件非便携式的事情时使用它。)(
unsigned
之间的转换不会改变类型)char *
和void *
是可移植的(如果你真的很挑剔,你实际上可以使用static_cast
)。
C风格演员表的问题是:当指针类型改变时,增加的灵活性会导致心痛。
注意:我同意尽可能不投射的一般惯例。但是,如果没有提供任何来源,这是我能做的最好的。
答案 1 :(得分:3)
您不能简单地将void*
转换为std::vector<unsigned char>
,因为后者的内存布局包括其他对象,例如当前分配的大小和字节数。
假设buf
指向缓冲区且其长度为n
:
vector<unsigned char> vuc(static_cast<char*>(buf), static_cast<char*>(buf) + n);
将创建一个可以安全使用的缓冲区的副本。
[编辑:添加了static_cast<char*>
,这是指针算术所必需的。]
答案 2 :(得分:3)
你不应该做任何演员 - 全程停止。请发布一些说明你问题的代码 - 我真的不明白“(void *)buffer”是什么意思。
答案 3 :(得分:3)
这是合法的唯一一次,如果你已经创建了一个向量,并且只是想把它取回来。
void SomeFunc(void* input);
main() {
std::vector< unsigned char > v;
SomeFunc((void*) &v);
}
SomeFunc(void* input) {
// Now, you could cast that void* into a vector
std::vector< unsigned char >* v_ = (vector<unsigned char>*)input
}
我实际上并没有试图看看它是否会运行,但这就是它的精神。也就是说,如果你是从头开始做这件事,你肯定做错了。这真的很糟糕。唯一可以远程理解的是,如果你被迫实现已经定义的“SomeFunc()”。
答案 4 :(得分:2)
对已经分配的缓冲区使用std :: vector类不是解决方案。 std :: vector对象管理内存并在销毁时解除分配。
一个复杂的解决方案可能是编写自己的分配器,它使用已经分配的缓冲区,但你必须在几个场景中非常小心,比如矢量大小调整等。
如果你通过一些C API函数绑定了void * buffer,那么你可以忘记转换为std :: vector。
如果您只需要该缓冲区的副本,可以这样做:
std::vector< unsigned char> cpy(
(unsigned char*)buffer, (unsigned char*)buffer + bufferSize);
其中bufferSize是复制缓冲区的字符大小。