我有功能:
string f1 (unsigned char * value, int len)
{
...
}
我想传递给它的变量是
char buf[4096];
最好的方法是什么?
我有功能:
string f1 (unsigned char * value, int len)
{
...
}
我想传递给它的变量是
char buf[4096];
最好的方法是什么?
您可以将缓冲区的声明更改为预期的类型吗?如果是这样,我会推荐:
const unsigned int BUFFER_SIZE = 4096;
unsigned char buf[BUFFER_SIZE];
string result = f1(buf, BUFFER_SIZE);
如果您无法控制该变量,您可能会这样做
string result = f1(reinterpret_cast<unsigned char*>(buf), sizeof(buf)/sizeof(buf[0]));
我猜len
是指缓冲区中的元素数量(最好在 的文档中查找f1
)。您可以通过以下方式获得:
sizeof(buf) // as `sizeof(char)==1`
// or
sizeof(buf)/sizeof(buf[0]) // more commonly used, works with all types
这在这里作为sizeof(char) == sizeof(unsigned char) == 1
.
另一点是你不能打电话
f1(buf, len);
即使“buf
数组到 4096 个字符”可以隐式转换为“指向字符的指针”:如果没有/J
编译选项,Visual-C++ 的char
默认签名是-> signed char
。对于 A 和 B 两种类型,只有当 B 是 A 的基类(§4.10 conv.ptr)时,C++ 才会执行从“指向 A 的指针”到“指向 B 的指针”的转换。unsigned char
由于and不是这种情况signed char
,因此转换不是隐式的(不在标准转换序列中,§4 conv)。
但是,您可以使用 a 显式转换它reinterpret_cast
:
signed char as[4096];
int const len = sizeof(as)/sizeof(as[0]);
unsigned char* pu = reinterpret_cast < unsigned char* > (as);
f1(pu, len);
这是传递数组的最佳方式吗?
有一个微妙之处:如果该函数明确专门用于unsigned char
,它可能会“误解”传递的signed char
缓冲区的内容。此外,如果f1
更改数组,解释signed char
缓冲区的人可能会与所做的事情发生冲突f1
(如f1
在 的数组上工作的那样unsigned char
)。但是,如果您知道f1
缓冲区的作用和解释方式,则可以进行此转换。
重点是什么?为什么static_cast
这里不允许隐含或允许?signed
指针和类型
之间的转换可能存在特殊情况unsigned
(具有相同的对象表示),但我没有找到。基本上,一个人想避免像这样的演员:
short s = 42;
long* pl = &s;
*pl = 4000; // possibly stack corruption
long l = 4200;
short* ps = &l;
*ps = 42;
//- value of l dependent e.g. on endianess
背景/标准
我对它的reinterpret_cast
实际作用有点(或更多)好奇,所以这里的其余部分是关于标准所说的细节。实际上,reinterpret_cast
解析为(§5.2.10/7 expr.reinterpret.cast):
unsigned char* pu = static_cast < unsigned char* > ( static_cast < void* > (as) );
让我们详细介绍一下。
Inner static_cast < void* > (as)
:
static_cast
允许进行“数组到指针”转换(§5.2.9/8 expr.static.cast)和标准转换序列(§5.2.9/4,比较§4/3 conv)。标准转换序列允许从"pointer to A"到"pointer to void"的转换。它保证指向操作数的内存位置的开始。这很好,因为数组由一组连续分配的元素组成(§8.3.4 dcl.array)。
外部static_cast < unsigned char* >
:这是标准转换的逆 - 即,“指向无符号字符的指针”到“指向 void 的指针”(§5.2.9/7 + 13)。当我们从"pointer to signed char"通过"pointer to void"转换为"pointer to unsigned char"时,没有定义结果是什么(未指定)。注意char
和unsigned char
是不同的类型(§3.9.1/1 basic.fundamental)。但是在任何健全的机器/实现上都应该没问题,signed char
并且unsigned char
具有相同的对象表示。
令人惊讶的是f1((unsigned char*)buf, len);
会成功的。