【问题标题】:How to pass integer to CreateThread()?如何将整数传递给 CreateThread()?
【发布时间】:2012-09-26 08:04:08
【问题描述】:

如何将int参数传递给CreateThread回调函数?我试试看:

DWORD WINAPI mHandler(LPVOID sId) {
...
arr[(int)sId]
...
}

int id=1;
CreateThread(NULL, NULL, mHandler, (LPVOID)id, NULL, NULL);

但我收到警告:

warning C4311: 'type cast' : pointer truncation from 'LPVOID' to 'int'
warning C4312: 'type cast' : conversion from 'int' to 'LPVOID' of greater size

【问题讨论】:

    标签: c++ int createthread


    【解决方案1】:

    您可以通过使用适当的类型来消除此警告。在这种情况下,请使用 INT_PTR 或 DWORD_PTR(或任何其他 _PTR 类型)类型而不是 int(请参阅 MSDN 中的 Windows Data Types)。

    DWORD WINAPI mHandler(LPVOID p)
    {
        INT_PTR id=reinterpret_cast<INT_PTR>(p);
    }
    ...
    
    INT_PTR id = 123;
    CreateThread(NULL, NULL, mHandler, reinterpret_cast<LPVOID>(id), NULL, NULL);
    

    【讨论】:

      【解决方案2】:

      传递整数的地址而不是它的值:

      // parameter on the heap to avoid possible threading bugs
      int* id = new int(1);
      CreateThread(NULL, NULL, mHandler, id, NULL, NULL);
      
      
      DWORD WINAPI mHandler(LPVOID sId) {
          // make a copy of the parameter for convenience
          int id = *static_cast<int*>(sId);
          delete sId;
      
          // now do something with id
      }
      

      【讨论】:

      • 如果线程超出id的范围,就会出现问题
      • @ZdeslavVojkovic:不,没有。函数中的第一件事是按值制作副本。
      • 仍然不安全。如果直到 ID 超出范围(可能就在 CreateThread 调用之后)才安排新线程怎么办?
      • 抱歉,它不能正常工作。我在调试器中查看:我传入 CreateThread 0 -> 并接收 0,然后 1 -> -858993460 和程序崩溃......
      • 好的,使用newdelete 是安全的,但现在发送id 而不是&amp;id 就足够了——这应该在代码示例中作为线程函数进行修复假设它收到int* 而不是int**。这也是 BArtWell 在调试器中看到那些值/崩溃的原因
      【解决方案3】:

      我会用 CreateThread(..., reinterpret_cast&lt;LPVOID&gt;(static_cast&lt;INT_PTR&gt;(id)), ...); 在你的线程函数里面 int my_int = static_cast&lt;int&gt;(reinterpret_cast&lt;INT_PTR&gt;(sId));

      这也适用于枚举而不是int。 它应该可以在 32 位和 64 位模式下工作。

      【讨论】:

      • 强制转换参数类型可能会消除警告和错误,但它不会修复代码。如果该过程需要DWORD 的地址作为参数,那么您应该给它DWORD 的地址,而不仅仅是将“任意”值转换为看起来像地址的内容。
      • 官方文档指出,您可以传入标量值而不是指针。有些人使用单一的老式 C 演员表,但我不喜欢那样。出于某种原因,您可以将 INT_PTR 静态转换为 int,但不能将 LPVOID 静态转换为 int。因此,在第一步中,我将重新解释将 LPVOID 转换为 INT_PTR。两者都是指针,因此具有相同的大小(在 x86 模式下编译时为 32 位,在 64 位下编译时为 64 位)。此后,我静态转换为 int(32 位)。这样做没有问题,除非有人传入的不是 int,而是 64 位的值。
      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      相关资源
      最近更新 更多