QueryDosDeviceW 在线程中调用时始终返回 0

问题描述 投票:0回答:1
当从主线程以外的源调用时,

QueryDosDeviceW
返回 0。为什么?
我使用 Visual Studio 2022 (v143) 平台。 以下是测试代码和输出。

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include <windows.h>

std::vector<std::string> GetAvailableSerialPortsNames() {
  std::vector<std::string> com_names;
  TCHAR lp_target_path[5000];
  for (int i = 0; i <= 255; i++) { // checking ports from COM0 to COM255
    std::string com_name = "COM" + std::to_string(i); // converting to COM0, COM1, COM2
    DWORD Test 
      = QueryDosDeviceW((LPCWSTR)(
        std::wstring(com_name.begin(), com_name.end()).c_str()), 
        (LPWSTR)lp_target_path, 5000);
    if (Test != 0)
      com_names.push_back(com_name);
    if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      lp_target_path[10000]; // in case the buffer got filled, increase size of the buffer.
      continue;
    }
  }
  return com_names;
}

int main(void) {
  auto serials = GetAvailableSerialPortsNames();
  std::cout << "Querying in main thread. Ports count=" << serials.size() << std::endl;
  for (auto s : serials) std::cout << s << std::endl;

  std::thread([]() {
    auto serials = GetAvailableSerialPortsNames();
    std::cout << "Querying in other thread. Ports count=" << serials.size() << std::endl;
    for (auto s : serials) std::cout << s << std::endl;
  }).detach();
  
  std::this_thread::sleep_for(std::chrono::seconds(3));

  return 0;
}
Querying in main thread. Ports count=3
COM1
COM3
COM4
Querying in other thread. Ports count=0

------编辑

我本来是在Windows 10上使用Visual Studio 2019,这里没有任何问题。但是在Windows 11 Visual Studio 2022中构建时出现了这个问题。更改后的环境如下。
平台:

Visual Studio 2019 (v142) -> Visual Studio 2022 (v143)

Windows SDK 版本:
10.0.19041.0 -> 10.0.22621.0

-----编辑
按照留下评论的人的建议,我修复了有问题的代码,现在可以正常工作了。

std::vector<std::string> GetAvailableSerialPortsNames() {
  std::vector<std::string> com_names;
  TCHAR lp_target_path[10000];
  for (int i = 0; i <= 255; i++) { // checking ports from COM0 to COM255
    std::string com_name = "COM" + std::to_string(i); // converting to COM0, COM1, COM2
    DWORD test 
      = QueryDosDevice(com_name.c_str(), lp_target_path, 5000);
    if (test != 0) com_names.push_back(com_name);
  }
  return com_names;
}
Querying in main thread. Ports count=3
COM1
COM3
COM4
Querying in other thread. Ports count=3
COM1
COM3
COM4

我还是不明白。我做错的是参数的类型转换,但是为什么在主线程情况下却输出了正确的结果呢?

c++ winapi
1个回答
0
投票

将字符集从使用 Unicode 字符集更改为使用多字节字符集后,我可以重现它。我对原因不感兴趣,但正如 Windows API/函数原型约定中的 Unicode 所解释的那样,

您的应用程序应始终使用通用函数原型 通用字符串和字符类型。

enter image description here

enter image description here enter image description here enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.