Mam problem z kompilacją programu pochodzącego z książki “Praktyczne programowanie z Windows API w C++” autor nie podał w jakim kompilatorze można to skompilowac. Uznałem że jeśli chodzi o Windows API to najlepszy do tego będzie MS Visual C++ 2008 Express Edition.
Program:
#include
#include
#include
#include
#include
#define bufferLength 32
using namespace std;
void displayError(const char* msg)
{
cout << msg << endl;
system("PAUSE");
exit(0);
};
template
inline void releaseMemory(T &x)
{
assert(x != NULL);
delete x;
x = NULL;
}
GUID classGuid;
HMODULE hHidLib;
DWORD memberIndex = 0;
DWORD DeviceInterfaceDetailDataSize;
HDEVINFO DeviceInfoSet;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
HANDLE hidDeviceObject;
BYTE inputReportBuffer[bufferLength];
DWORD numberOfBytesRead = 0;
int main()
{
void (__stdcall *HidD_GetHidGuid)(OUT LPGUID HidGuid);
bool (__stdcall *HidD_GetNumInputBuffers)(IN HANDLE HidDeviceObject, OUT PULONG NumberBuffers);
hHidLib = LoadLibrary("HID.DLL");
if (!hHidLib)
displayError("Błąd podłączenia biblioteki HID.DLL");
(FARPROC&) HidD_GetHidGuid = GetProcAddress (hHidLib, "HidD_GetHidGuid");
(FARPROC&) HidD_GetNumInputBuffers = GetProcAddress (hHidLib, "HidD_GetNumInputBuffers");
if (!HidD_GetHidGuid)
{
FreeLibrary(hHidLib);
displayError("Nie znaleziono jednej lub więcej funkcji eksportowych. \n");
}
HidD_GetHidGuid(&classGuid);
DeviceInfoSet = SetupDiGetClassDevsA(&classGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
FreeLibrary(hHidLib);
displayError("Nie zidentyfikowano podłączonych urządzeń. \n");
}
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
while(SetupDiEnumDeviceInterfaces(DeviceInfoSet, NULL, &classGuid, memberIndex, &DeviceInterfaceData))
{
memberIndex++;
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, NULL, 0, &DeviceInterfaceDetailDataSize, NULL);
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
new DWORD[DeviceInterfaceDetailDataSize];
DeviceInterfaceDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, NULL, NULL))
{
releaseMemory(DeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
displayError("Nie można pobrac informacji o interfejsie. \n");
}
if (NULL != strstr(DeviceInterfaceDetailData->DevicePath, "vid_22ba"))
{
cout << "\n" << DeviceInterfaceDetailData->DevicePath << "\n";
hidDeviceObject = CreateFile(DeviceInterfaceDetailData->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hidDeviceObject == INVALID_HANDLE_VALUE)
displayError("Nie można otworzyc urzadzenia do transmisji");
else
break;
}
releaseMemory(DeviceInterfaceDetailData);
};
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
ULONG numberBuffers;
HidD_GetNumInputBuffers(hidDeviceObject, &numberBuffers);
printf("liczba buforów wejściowych = %d\n", numberBuffers);
while(true)
{
memset(&inputReportBuffer,0x00, sizeof(inputReportBuffer));
ReadFile(hidDeviceObject, inputReportBuffer, sizeof(inputReportBuffer), &numberOfBytesRead, NULL);
printf(" %d %d %d %d %d %d %d %d\n", inputReportBuffer[0],
inputReportBuffer[1], inputReportBuffer[2], inputReportBuffer[3], inputReportBuffer[4], inputReportBuffer[5], inputReportBuffer[6], inputReportBuffer[7]);
if (inputReportBuffer[6] == 64)
break;
}
Win32Check(CloseHandle(hidDeviceObject));
FreeLibrary(hHidLib);
cout << endl;
system("PAUSE");
return 0;
}
Kompilator pokazuje takie błędy:
------ Build started: Project: KontrolerUSB, Configuration: Debug Win32 ------
Compiling...
main.cpp
c:\program files\microsoft visual studio 9.0\vc\include\sysdefs.h(11) : fatal error C1189: #error : BCW 5.0 or greater required
Build log was saved at "file://c:\Users\Jakub\Documents\Visual Studio 2008\Projects\KontrolerUSB\KontrolerUSB\Debug\BuildLog.htm"
KontrolerUSB - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Natomiast gdy wyłącze funkcję:
Win32Check(CloseHandle(hidDeviceObject));
i plik:
#include
To kompilator pokazuje:
------ Build started: Project: KontrolerUSB, Configuration: Debug Win32 ------
Compiling...
main.cpp
Linking...
LINK : warning LNK4199: /DELAYLOAD:/DELAYLOAD:[setupapi.dll] ignored; no imports found from /DELAYLOAD:[setupapi.dll]
Main.obj : error LNK2019: unresolved external symbol __imp__ SetupDiDestroyDeviceInfoList@4 referenced in function _main
Main.obj : error LNK2019: unresolved external symbol __imp__ SetupDiGetDeviceInterfaceDetailA@24 referenced in function _main
Main.obj : error LNK2019: unresolved external symbol __imp__ SetupDiEnumDeviceInterfaces@20 referenced in function _main
Main.obj : error LNK2019: unresolved external symbol __imp__ SetupDiGetClassDevsA@16 referenced in function _main
C:\Users\Jakub\Documents\Visual Studio 2008\Projects\KontrolerUSB\Debug\KontrolerUSB.exe : fatal error LNK1120: 4 unresolved externals
Build log was saved at "file://c:\Users\Jakub\Documents\Visual Studio 2008\Projects\KontrolerUSB\KontrolerUSB\Debug\BuildLog.htm"
KontrolerUSB - 5 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Program wydaje się dobrze przepisany ale nie wiem czy kompilator jest dobrze ustawiony a właściwie linker…