各种函数链接库错误(无法解析的外部符号)
本人新手对于如何包含动态链接库也不是很了解,请问这种情况应该怎么配置?
代码如下,就是想根据vID pID找到指定的设备。
函数中SetupDi······,Hid_Get...都报无法解析错误
(CSDN新人,1个C币是全部家当了,跪求)
#include "stdafx.h"
#include "afxwinappex.h"
#include "afxdialogex.h"
#include "CommTest.h"
#include "MainFrm.h"
#include "CommTestDoc.h"
#include "CommTestView.h"
extern "C" {
//declare the C libraries used
#include "setupAPI.h"
#include "hidsdi.h"
}
BOOL CCommTestWindow::DeviceOpen(HANDLE &handle, WORD wVID, WORD wPID)
{
BOOL bRet = FALSE;
GUID hidGuid;
HDEVINFO hardwareDeviceInfo;
SP_INTERFACE_DEVICE_DATA deviceInfoData;
PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = NULL;
ULONG predictedLength = 0;
ULONG requiredLength = 0;
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
deviceInfoData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
HidD_GetHidGuid(&hidGuid);
hardwareDeviceInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
for (int i = 0; i<128; i++)
{
if (!SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, 0, &hidGuid, i, &deviceInfoData)) continue;
SetupDiGetDeviceInterfaceDetail(hardwareDeviceInfo, &deviceInfoData, NULL, 0, &requiredLength, NULL);
predictedLength = requiredLength;
functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(predictedLength);
if (!functionClassDeviceData) continue;
functionClassDeviceData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hardwareDeviceInfo, &deviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) break;
handle = CreateFile(functionClassDeviceData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
HIDD_ATTRIBUTES attri;
HidD_GetAttributes(handle, &attri);
if ((attri.VendorID == wVID) && (attri.ProductID == wPID))
{
bRet = TRUE;
break;
}
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
}
SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
return bRet;
}
原因一:用户自定义的类中的函数声明与函数定义分开写时,函数名写的不一致,往往初学者比较容易犯这样的毛病,比如,在类的头文件Point.h里声明了void setX(int aX);函数,在Point.cpp文件中写该函数的定义时确写成了void Point::setx(int aX){},由于C++语言是区分大小写的编程语言,所以在编译时认定为只有该函数setX的声明,没有其定义,当然这种情况往往容易发现错误,因为计算机会先报语法声明错误,告知setx函数没有在类Point中声明,然而,可怕的是在.h文件里声明了setX函数,却忘记了在.cpp文件里定义,这时,在程序中调用过几次setX函数就会出现几个link链接错误,初学者往往由于大量的链接错误而灰心丧气,其实如果知道原因了修改起来并不难。
避错方案:将声明好的类写好后,复制,然后粘贴到.cpp文件中完成其定义过程,需要提醒的是,注意去掉每个函数声明后面的分号。
原因二:未引入链接库.lib文件,这个多发生在使用第三方开发库的情况下,比如,我在博客中系列提到的SDL开发,开发时需要在编译的时候链接SDL提供的lib库,如果没有通过配置的方式(配置的方法请参考我前面SDL配置相关文章,这里不做赘述)添加相关.lib文件或者通过#pragma comment(lib, 'SDL.lib')提供lib的链接,那么计算机会因为找不到所调用函数的代码段(这种情况下,只有头文件,代码段被编译好了放在.lib文件里)而报link错误,改正的方法就不言而喻了。
避错方案:先看自己的工程有没有用到第三方开发环境,如果用到了,请先把这些配好,再开始后续的开发工作。另外,不是只有第三方开发环境才需要配置相应的 .lib文件,当我们在VS2005/2008(暂且以他们为例,其它同理)中,按alt+F7打开工程属性页后,点选配置属性-->链接器-->输入,可以看到默认添加好的lib文件如下:
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib
在开发过程中如果用到之外的库(这种情况在学习C++时很少遇到)就必须要手动添加了。
原因三:没有将项目需要的头文件、源文件都加入项目中。这个经常会有人犯,可以进行排查。
避错方案:细心,另外就是在写程序时发现自己用到了新的类型就立刻把该类型的头文件添加(其实就是#include进来),如果写完某对象在其后加“.”后IDE环境不能智能弹出数据成员和成员函数,那么也要注意了,一般是因为你没有添加相应的头文件造成的。当然IDE环境出问题的情况也有,毕竟很少,区别对待即可。
原因四:当__declspec(dllexport)函数与inline函数混用并要生成.exe的工程也会偶然产生这种错误,这种错误我在最近做实验的时候遇到,目前具体原因不详,在新的工程中做写简单代码测试后也没有再产生link错误,最后解决的办法是去掉了inline(本身这个是建议性的语法,所以去掉后不影响编译),结果问题就解决了,也顺利通过了。
避错方案:在写exe工程时,不要写__declspec(dllexport)符号,本身这个符号是编译dll时使用的导出符号,符号用的多了难免冲突,在不明原因的情况下也很难排错。
可是并没有解决问题啊,这个程序应该是用到了WDK的东西,但是不知道该怎么添加库,在哪里添加