使用 Windows SetupAPI 與 HID API 進行 USB 設備枚舉與通信時,LNK2019 無法解析的外部符號 是新手最常遇到的阻礙。本文系統梳理四大核心原因與對應解決方案,助你徹底搞定鏈接配置。
錯誤 LNK2019: 無法解析的外部符號 _HidD_GetHidGuid@4,函數 "BOOL __cdecl DeviceOpen(...)" 中引用該符號
錯誤 LNK2019: 無法解析的外部符號 _SetupDiGetClassDevs@16,函數 "BOOL __cdecl DeviceOpen(...)" 中引用該符號
... 類似 SetupDiEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail, HidD_GetAttributes 等
代碼僅 #include <setupapi.h>, <hidsdi.h>,但未鏈接對應 .lib。
// 方案 A:專案屬性配置(推薦)
// 右鍵專案 → Properties → Linker → Input → Additional Dependencies
setupapi.lib; hid.lib;
// 方案 B:代碼中指定(MSVC 專用)
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "hid.lib")
SetupDiGetClassDevsW (寬字符版)SetupDiGetClassDevsA 需對應 setupapi.lib 仍同,但參數類型必須匹配SetupDiGetClassDevs,配合 TCHAR/LPCTSTR,由編譯器自動映射#include <initguid.h> 在 <devguid.h> 之前,確保 GUID 定義正確HidD_GetHidGuid 原型:VOID HidD_GetHidGuid(LPGUID HidGuid);// stdafx.h 或 pch.h
#pragma once
#include
#include
#include
#include // 關鍵:確保 GUID 定義
#include // 系統設備類 GUID
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "hid.lib")
// DeviceOpen.cpp
BOOL DeviceOpen(HANDLE& handle, WORD wVID, WORD wPID) {
GUID hidGuid;
HidD_GetHidGuid(&hidGuid); // 獲取 HID 類 GUID
HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) return FALSE;
SP_DEVICE_INTERFACE_DATA devData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &hidGuid, i, &devData); ++i) {
DWORD reqSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devData, NULL, 0, &reqSize, NULL);
PSP_DEVICE_INTERFACE_DETAIL_DATA detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(reqSize);
detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &devData, detail, reqSize, NULL, NULL)) {
handle = CreateFile(detail->DevicePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (handle != INVALID_HANDLE_VALUE) {
HIDD_ATTRIBUTES attrs = { sizeof(HIDD_ATTRIBUTES) };
if (HidD_GetAttributes(handle, &attrs) &&
attrs.VendorID == wVID && attrs.ProductID == wPID) {
free(detail);
SetupDiDestroyDeviceInfoList(hDevInfo);
return TRUE;
}
CloseHandle(handle);
}
}
free(detail);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return FALSE;
}
dumpbin /exports setupapi.lib | findstr HidD_GetHidGuid 確認符號存在/VERBOSE:LIBstdafx.h 正確包含並預編譯遵循「頭文件宣告 + #pragma comment(lib) + Unicode 字符集 + initguid.h」四步法,可 100% 解決 HID/SetupAPI 鏈接問題。