将 struct 转换为 unsigned char *

发布于 2024-07-26 14:55:52 字数 378 浏览 6 评论 0原文

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

How can I convert the following struct to 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

北凤男飞 2024-08-02 14:55:52

您不能在此处使用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 );
}

You can't use a static_cast here since there is no relationship between the types. You would have to use reinterpret_cast.

Basically, a static_cast should be used in most cases, whereas reinterpret_cast should probably make you question why you are doing it this way.

Here is a time where you would use static_cast:

class Base {
};

class Derived : Base {
};

Base* foo = new Derived;
Derived* dfoo = static_cast<Derived*>( foo );

Whereas here is where you would probably need a reinterpret_cast:

void SetWindowText( WPARAM wParam, LPARAM lParam )
{
   LPCTSTR strText = reinterpret_cast<LPCTSTR>( lParam );
}
忆离笙 2024-08-02 14:55:52

由于结构打包差异,如果不首先使用数组或编写一些代码来按名称从结构成员一次填充一个新数组,则无法可靠且可移植地完成此操作。 reinterpret_cast 可能在一个编译器/平台/版本上工作,但在另一个编译器/平台/版本上可能会中断。

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

Due to struct packing differences, you can't do this reliably and portably without either using an array to begin with or writing some code that filled a new array one at a time from the struct members by name. A reinterpret_cast might work on one compiler/platform/version and break on another.

You're better off allocating an array on the heap or stack, and then filling it one by one.

零時差 2024-08-02 14:55:52

尝试reinterpret_caststatic_cast 用于在兼容类型之间进行转换,例如基类到派生类。 reinterpret_cast 用于不相关类型之间的转换。

Try reinterpret_cast<unsigned char*>. static_cast is for converting between compatible types, like a base class to a derived class. reinterpret_cast is for casts between unrelated types.

鸵鸟症 2024-08-02 14:55:52

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

unsigned char uc[5];

然后您可以单独将其寻址为 uc[0]、uc[1]、uc[2]、uc[3]、uc[4] 并通过指向聚合的指针(大概是您想要的 unsigned char * )“ UC”。

看起来比具有多个在成员名称中编号的无符号 char 成员的结构简单得多(顺便说一句,uc4 发生了什么? - 数组解决方案将避免的另一个错误。)

Why would you use such a strange struct instead of:

unsigned char uc[5];

which you can then individually address as uc[0], uc[1], uc[2], uc[3], uc[4] and by pointer to the aggregation (presumably what you want with unsigned char *) by just "uc".

Seems a lot simpler than a struct with multiple unsigned char members that are numbered in the member names (and btw, what happened to uc4? -- another error the array solution would avoid.)

随风而去 2024-08-02 14:55:52

简单来说怎么样:

unsigned char * uc_ptr2 = &uc_ptr->uc1;

How about simply:

unsigned char * uc_ptr2 = &uc_ptr->uc1;
八巷 2024-08-02 14:55:52

将 POD(即 C 兼容结构)类型转换为无符号 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);

我怀疑您应该可以接受对齐问题是因为您的结构包含可以在任何字节对齐的无符号字符,因此编译器不会在成员之间插入任何包装(但严格来说,这是依赖于实现的,因此请谨慎使用)。

The safest, most portable way to convert POD (i.e. C compatible structs) types to unsigned char pointers is not by using reinterpret_cast but by using static_cast (C++0x fixes this and empowers reinterpret_cast to unambiguously have the same portable semantics as the following line of code):

unsigned char *uc_ptr2 = static_cast<unsigned char*>(static_cast<void*>(uc_ptr));

But for all practical purposes, even though the C++03 standard is thought to be somewhat ambiguous on the issue (not so much when converting pointers of class types, but when converting pointers of non-class types to 'unsigned char*'), most implementations will do the right thing if you do use reinterpret_cast as so:

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

I suspect that you should be fine with alignment issues since your struct contains unsigned chars which can be aligned at any byte, so the compiler won't insert any packing between the members (but strictly speaking, this is implementation dependent, so use caution).

面如桃花 2024-08-02 14:55:52

在这种情况下,使用 reinterpret_cast 强制转换为 unsigned char* 保证有效,并将指向第一个 unsigned char 数据成员,因为您的类型是一个所谓的 POD 结构体(大致是一个 C 结构体)。

标准引用(来自 9.2/17,如果你想看的话)

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

所以下面的作品

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

In this case, casting with reinterpret_cast to unsigned char* is guaranteed to work and will point to the first unsigned char data member, because your type is a so-called POD struct (roughly, a C struct).

Quote of the Standard (from 9.2/17, if you wanna look)

A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]

So the following works

unsigned char * uc_ptr2 = reinterpret_cast<unsigned char*>(uc_ptr);
简美 2024-08-02 14:55:52

您是否想将结构的地址转换为无符号字符的地址(如某些答案所假设的那样)或将实际结构转换为指针(如您的问题所示)? 如果是前者,这里有几种可能性:

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;

Do you want to convert the address of the struct to an address of an unsigned char (as some of the answers assume) or the actual struct to a pointer (as your question indicates)? If the former, here are a few possibilities:

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;

If the latter, you can use one of:

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;
烛影斜 2024-08-02 14:55:52

一种选择是反其道而行之。 首先创建“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;
}

One option is to do the reverse. Create your "unsigned char *" buffer first and then use placement new to allocate your object on top of this buffer.

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文