繁体   English   中英

将struct转换为unsigned char *

[英]Convert struct to unsigned char *

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

你不能在这里使用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 );
}

由于结构填充差异,如果没有使用数组开始或者从结构成员按名称一次编写一些填充新数组的代码,则无法可靠且可移植地执行此操作。 reinterpret_cast可能在一个编译器/平台/版本上工作,在另一个上打破。

你最好在堆或堆栈上分配一个数组,然后逐个填充它。

尝试reinterpret_cast<unsigned char*> static_cast用于在兼容类型之间进行转换,例如基类到派生类。 reinterpret_cast用于不相关类型之间的强制转换。

为什么要使用这样一个奇怪的结构而不是:

unsigned char uc [5];

然后您可以单独地将其作为uc [0],uc [1],uc [2],uc [3],uc [4]以及指向聚合的指针(可能是您想要的无符号字符*)通过“ UC”。

看起来比具有多个unsigned char成员的结构简单得多,这些成员在成员名称中编号(和btw,uc4发生了什么? - 数组解决方案会避免的另一个错误。)

怎么样简单:

unsigned char * uc_ptr2 = &uc_ptr->uc1;

将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包含可以在任何字节对齐的无符号字符,因此编译器不会在成员之间插入任何包装(但严格来说,这是依赖于实现的,所以要小心) 。

在这种情况下,使用reinterpret_castunsigned char*可以保证工作并指向第一个unsigned char数据成员,因为您的类型是所谓的POD结构(大致是C结构)。

标准报价(从9.2/17 ,如果你想看)

指向POD结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 [注意:因此,在POD-struct对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐。 ]

以下是有效的

unsigned char * uc_ptr2 = reinterpret_cast<unsigned char*>(uc_ptr);

是否要将结构的地址转换为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;

一种选择是反过来。 首先创建“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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM