如何将以下struct
转换为unsigned char*
?
typedef struct {
unsigned char uc1;
unsigned char uc2;
unsigned char uc3;
unsigned char uc5;
unsigned char uc6;
} uchar_t;
uchar_t *uc_ptr = new uchar;
unsigned char * uc_ptr2 = static_cast<unsigned char*>(*uc_ptr);
// invalid static cast at the previous line
答案 0 :(得分:7)
您不能在此使用static_cast
,因为类型之间没有关系。您必须使用reinterpret_cast
。
基本上,在大多数情况下应该使用static_cast
,而reinterpret_cast
可能会让你质疑为什么这样做。
以下是您使用static_cast
的时间:
class Base {
};
class Derived : Base {
};
Base* foo = new Derived;
Derived* dfoo = static_cast<Derived*>( foo );
而这里您可能需要reinterpret_cast
:
void SetWindowText( WPARAM wParam, LPARAM lParam )
{
LPCTSTR strText = reinterpret_cast<LPCTSTR>( lParam );
}
答案 1 :(得分:4)
由于结构填充差异,如果没有使用数组开始,或者从结构成员按名称一次编写一些填充新数组的代码,则无法可靠且可移植地执行此操作。 reinterpret_cast可能在一个编译器/平台/版本上运行,而在另一个编译器/平台/版本上运行。
最好在堆或堆栈上分配一个数组,然后逐个填充它。
答案 2 :(得分:2)
试试reinterpret_cast<unsigned char*>
。 static_cast
用于在兼容类型之间进行转换,例如基类和派生类。 reinterpret_cast
用于不相关类型之间的转换。
答案 3 :(得分:1)
为什么要使用这样一个奇怪的结构而不是:
unsigned char uc [5];
然后你可以单独地将其作为uc [0],uc [1],uc [2],uc [3],uc [4]和指向聚合的指针(可能是你想要的unsigned char *)只是“uc”。
看起来比具有多个unsigned char成员的结构简单得多,这些成员在成员名称中编号(和btw,uc4发生了什么? - 数组解决方案会避免的另一个错误。)
答案 4 :(得分:1)
简单地说:
unsigned char * uc_ptr2 = &uc_ptr->uc1;
答案 5 :(得分:1)
将POD(即C兼容结构)类型转换为unsigned char指针的最安全,最便携的方法不是使用reinterpret_cast
,而是使用static_cast
(C ++ 0x修复此问题并赋予reinterpret_cast权限)明确地具有与以下代码行相同的可移植语义:
unsigned char *uc_ptr2 = static_cast<unsigned char*>(static_cast<void*>(uc_ptr));
但是出于所有实际目的,即使C ++ 03标准在这个问题上被认为有些模棱两可(在转换类类型的指针时不是那么多,但是在将非类类型的指针转换为'unsigned char'时*'),如果您使用reinterpret_cast
,大多数实现都会做正确的事情:
unsigned char *uc_ptr2 = reinterpret_cast<void*>(uc_ptr);
我怀疑你应该没有对齐问题,因为你的struct包含可以在任何字节对齐的无符号字符,所以编译器不会在成员之间插入任何包装(但严格来说,这是依赖于实现的,所以谨慎使用。)
答案 6 :(得分:1)
在这种情况下,使用reinterpret_cast
转换为unsigned char*
可以保证正常工作并指向第一个unsigned char
数据成员,因为您的类型是所谓的POD结构(大致,一个C结构)。
标准的引用(来自9.2/17
,如果你想看)
指向POD结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然。 [注意:因此,在POD-struct对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐。 ]
以下作品
unsigned char * uc_ptr2 = reinterpret_cast<unsigned char*>(uc_ptr);
答案 7 :(得分:0)
是否要将结构的地址转换为unsigned char的地址(如某些答案所假设的)或实际结构转换为指针(如问题所示)?如果是前者,这里有几种可能性:
unsigned char * uc_ptr2 = static_cast<unsigned char *>(static_cast<void *>(uc_ptr));
unsigned char * uc_ptr2 = reinterpret_cast<unsigned char *>(uc_ptr);
unsigned char * uc_ptr2 = (unsigned char *)uc_ptr;
如果是后者,您可以使用以下之一:
unsigned char * uc_ptr2 = *static_cast<unsigned char **>(static_cast<void *>(uc_ptr));
unsigned char * uc_ptr2 = *reinterpret_cast<unsigned char **>(uc_ptr);
unsigned char * uc_ptr2 = *(unsigned char **)uc_ptr;
答案 8 :(得分:0)
一种选择是反过来。首先创建“unsigned char *”缓冲区,然后使用placement new将对象分配到此缓冲区之上。
#include <iostream>
struct uchar_t {
unsigned char uc1;
unsigned char uc2;
unsigned char uc3;
unsigned char uc4;
unsigned char uc5;
unsigned char uc6;
};
int main ()
{
unsigned char * buffer
= new unsigned char[ sizeof (uchar_t)/sizeof (unsigned char) ];
uchar_t * uc = new (buffer) uchar_t ();
uc->uc3 = 'a';
std::cout << buffer[2] << std::endl;
delete buffer;
}