【问题标题】:How do I send floats in window messages如何在窗口消息中发送浮点数
【发布时间】:2011-01-30 17:20:58
【问题描述】:

使用 c++ 强制转换运算符在 windows 消息中发送浮点数的最佳方式是什么?

我问的原因是我首先想到的方法不起作用。作为记录,我使用标准的 win32 函数发送消息:

PostWindowMessage(UINT nMsg,WPARAM wParam,LPARAM lParam)

什么不起作用:

  • 使用static_cast<WPARAM>() 不起作用,因为WPARAM 被typedef'ed 为UINT_PTR 并将进行从float 到int 的数字转换,有效地截断float 的值。
  • 使用 reinterpret_cast<WPARAM>() 不起作用,因为它是为指针使用而失败并出现编译错误。

目前我能想到两种解决方法:

  • reinterpret_cast 与运算符的地址结合使用: 浮动 f = 42.0f; ::PostWindowMessage(WM_SOME_MESSAGE, *reinterpret_cast(&f), 0);
  • 使用联合: 联合 { WPARAM wParam,浮动 f }; f = 42.0f; ::PostWindowMessage(WM_SOME_MESSAGE, wParam, 0);

其中哪些是首选?还有其他更优雅的方式来实现这一点吗?

【问题讨论】:

  • 我不建议通过称为“PostWindowMessage”的东西向临时对象发送指针,因为它应该是异步的。
  • 指针在调用时被取消引用(演员前的星号),没有临时地址发送到 PostWindowMessage
  • @Kirill 我不会向临时人员发送指针。我正在获取浮点数的地址,将该地址转换为指向 WPARAM 的指针,并将该地址解析为按值传递的 WPARAM。指针仅用于欺骗编译器不转换值。
  • @Vincent Robert,好的,我现在看到了。

标签: c++ winapi


【解决方案1】:

使用reinterpret_cast< WPARAM &>(f)。这种转换不限于指针,它也适用于引用。

【讨论】:

  • 谢谢!这正是我想要的。
【解决方案2】:

你可以使用 memcpy:

#include <memory.h>
int main() {
    float f = 1.0;
    int n;
    memcpy( &n, &f, sizeof(f) );
}

我不认为有一个优雅的解决方案,但无论你做什么,我都会将它包装在一个函数中,以明确我在做什么:

int FloatToInt( float f ) {
    int n;
    assert( sizeof(n) == sizeof(f) );
    memcpy( &n, &f, sizeof(f) );
    return n;
}

【讨论】:

  • +1 这是最安全的方法。理论上使用reinterpret_cast OP 的方式是未定义的行为,尽管在实践中它可能会起作用......
  • 我要添加if ( sizeof float == sizeof int )
  • @Kirill 我不会,但我可能会添加一个断言。
  • WPARAM 几乎不是可移植的类型。我认为这种情况甚至不需要断言。在 Win32 和 Win64 上,浮点数不比指针大,在 Win128 上假设相同是完全合理的。
  • 在这个答案中 FloatToInt 返回 int 而不是 WPARAM
【解决方案3】:

我更喜欢工会。这是最清楚和最容易理解的。它也可能具有最少的未定义行为。

【讨论】:

  • 嘿,说得好:“最少的未定义行为”。 :P
  • 以这种方式使用联合(保存一个成员并从另一个成员读取)会引发未定义的行为。
  • 请查看this post,类型双关语是在 C 中定义的行为,但在 C++ 中没有。 memcpy 之类的东西可能比等效的联合代码更安全。
【解决方案4】:

我会采用简单的方法,将指向您的 float 的指针转换为指向 UINT 的指针,然后取消引用生成的指针:

WPARAM wParam = *((UINT*)(&f));

要将它转换回来,你做相反的事情。在指针级别进行强制转换确保编译器不会在你背后尝试任何“转换”。

float f = *((float*)(&wParam))

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多