【问题标题】:How to access an attribute into a struct from a void pointer?如何从 void 指针将属性访问到结构中?
【发布时间】:2016-01-27 07:48:41
【问题描述】:

我得到了一个任务,我看不到函数的详细功能,但我只知道 id 一般做什么。

所以我有一个函数,我们称之为“get_button”,在文档中我知道“它返回一个指向按钮结构的指针”。我知道按钮结构,它类似于:

struct button{
    int size;
    char title;
    short keyID;
};

函数类似于:

void * get_button(int ID, int group)

但我不知道它是做什么的。

现在我想知道标题,但是在使用编译器时我得到了一个 void 指针作为回报。那么我应该如何使用这个 void 指针呢? ASAIK 我必须使用 static_cast 来引用它,但在这种情况下是一个结构;此外,我无法真正理解强制转换的含义以及如何让编译器知道我想要某个结构。

这是一个特殊情况,我需要知道如何将参数从 void 指针获取到结构中。我不知道我是否应该使用 static_cast 或其他什么(所以我无法理解对它的引用)。在这种情况下,我也不需要知道如何使用 void 指针!我只需要知道如何访问结构中的属性。 我在这里和那里看到了其他答案,但我找不到对这个案例有价值的东西。

【问题讨论】:

  • 空指针只是一个指针,它没有指定它所指向的类型。如果您确定它实际上指向某个结构,则可以将其转换为指向该结构的指针(使用static_cast 或普通的 C 样式转换),然后正常使用它。但是,如果您使用的库为您提供 void 指针,那么它可能是故意为您提供“不透明句柄”,您应该将其传递给相关的库函数以实际使用它。有关您正在使用的库和/或上下文的更多详细信息可以帮助我们提供相关建议
  • 我只知道函数调用,但我不知道函数指令。我被告知“它返回一个指向结构的指针”,而不是其他东西。我正在使用以前用 C 编程但最近才用 c++ 编程的嵌入式机器。我只知道按钮结构,定义在一个 key.h 库(包含在 ofc 程序中)中,类似于我写的东西。我没有更多信息。

标签: c++ pointers struct


【解决方案1】:

我真的不明白强制转换是什么意思

您在下一个问题中回答自己:

如何让编译器知道我想要某个结构。

就是这样。强制转换意味着您告诉编译器该对象具有特定类型。

这是一个特殊情况,我需要知道如何将参数从 void 指针获取到结构中。

首先,将 void 指针转换为它指向的对象的指针类型:*button。然后你就可以正常访问属性了,在正确类型的指针上使用operator->

我不知道我是否应该使用 static_cast 或其他什么

当将 void 指针转换为另一种指针类型时,您确实应该使用 static_cast

void* void_pointer = get_button(ID, group); // get the pointer
button* button_pointer = static_cast<button*>(void_pointer); // cast to the type of the pointed object
int size = button_pointer->size; // access the attribute through the pointer

【讨论】:

  • 谢谢你的回答,我现在可以试试别的。但是在这种情况下我无法理解的是:为什么架构师一开始没有使用返回结构指针?他知道唯一可能的演员将是那个特定的结构。
  • @MarkWuji 您需要向架构师询问明确的答案。你确定这是唯一可能的演员阵容吗?也许该函数也可以返回指向其他类型对象的指针。
  • 是的。文档告诉“此函数返回使用 ID 指定的按钮结构的地址”。问题是,我不能问建筑师,他不再和我的公司合作了。我正在做肮脏的工作:)无论如何我会尝试这个解决方案,看起来不错,但它只是在我的机器上造成了系统故障:) 谢谢你的建议。
  • @MarkWuji 好吧,鉴于该文档,除了button 之外,是否还有 other 按钮结构?也许没有,但将来可能会有?如果函数只返回指向单一类型对象的指针,并且不打算返回任何其他对象,那么返回 void 指针就没有任何意义。
  • 我的程序仍然有问题,但您的回答实际上是正确的;谢谢你:)
【解决方案2】:

这是一个简单的 C 旧样式的示例,将您的结构转换为 void 指针:

#include <iostream>

using namespace std;

struct button{
    int size;
    char title;
    short keyID;
};

int main()
{
    button b;
    b.size  = 1;
    b.title = 'c';
    b.keyID = 2;
    void *p = &b;
    button *a = (button *)p;
    std::cout << a->size << std::endl;
    std::cout << a->title << std::endl;
    std::cout << a->keyID << std::endl;
    return 0;
}

【讨论】:

    【解决方案3】:

    指针基本上是内存中某物所在位置的地址,在您的情况下是按钮结构。 当指针的类型更改为 void* 时,该地址不会更改,因此如果您的库提供 get_button 函数保证返回的指针实际上将指向有效的按钮结构,您可以安全地将其转换回按钮* 为了使用它(认为它为编译器提供了一些额外的信息)。

    你可以这样做:

    void *what_is_returned = get_button();
    button *the_button = static_cast<button *>(what_is_returned);
    char the_character_you_want = the_button->title;
    

    -> 操作符的意思是“解引用和访问成员”,它是解引用左侧变量包含的内容(查找地址,如 *the_button)然后访问成员(如 (*the_button) .title),有效地将按钮结构中标题成员的偏移量添加到按钮的地址并从那里获取字符。

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 2021-01-08
      • 2012-02-03
      • 2014-05-14
      • 1970-01-01
      • 2012-10-11
      • 2021-08-05
      • 1970-01-01
      • 2021-09-29
      相关资源
      最近更新 更多