将struct转换为unsigned char *

时间:2009-07-08 04:02:53

标签: c++ type-conversion static-cast

如何将以下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

9 个答案:

答案 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;
}