- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我问@Stackoverflow 有点新,但这是我所拥有的最接近圣经的东西(除了 Ritchie 的 C 书),特别是在我的大多数主题的期末项目的这些日子里。无论如何,我的问题是关于与 HID 设备通信的应用程序所需的库以及使用 C++ 进行通信的可能性。
我不需要固件方面的帮助,我的设备已经按照我期望的方式工作。然而,我唯一的 HID 设备编程经验是使用 C(Windows - VS2010),现在我正在编译器类的最终项目中,我们将信息发送到带有矩阵屏幕的设备以显示“东西” ”。然而,我的合作伙伴需要用 C++ 做一些事情,这可以为我们节省很多时间(考虑到它在两天内到期,这是一件不错的事情)。
这个问题的全部意义在于询问它是否可以按照我在 C 中已有的方式(具有明显的调整)和 C++< 中的部分代码来完成/strong> 仍然与 SetupApi.DLL 和 HID.DLL 兼容
非常感谢任何类型的建议、指示或说明。我包含了我到目前为止使用的代码。
请原谅我可能会有的所有西类牙语和困惑的评论
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#include <SETUPAPI.H>
//----------------------------------------------
#define RICH_VENDOR_ID 0x0000
#define RICH_USBHID_GENIO_ID 0x2012
#define INPUT_REPORT_SIZE 5
#define OUTPUT_REPORT_SIZE 2
//----------------------------------------------
char c=0x0;
DWORD BytesRead = 0;
DWORD BytesWritten = 0;
unsigned char reporteEntrada[INPUT_REPORT_SIZE+1];
unsigned char reporteSalida[OUTPUT_REPORT_SIZE+1];
int status = 0;
static unsigned char dato = 0x01;
static unsigned char numLED = 1;
unsigned char palabra[192]={0};
int desplegar,valorled;
desplegar=0;
valorled=0;
unsigned char temporal;
//unsigned char ch;
//unsigned int index;
typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
typedef VOID (__stdcall *PHidD_GetProductString)(HANDLE, PVOID, ULONG);
typedef VOID (__stdcall *PHidD_GetHidGuid)(LPGUID);
typedef BOOLEAN (__stdcall *PHidD_GetAttributes)(HANDLE, PHIDD_ATTRIBUTES);
typedef BOOLEAN (__stdcall *PHidD_SetFeature)(HANDLE, PVOID, ULONG);
typedef BOOLEAN (__stdcall *PHidD_GetFeature)(HANDLE, PVOID, ULONG);
//----------------------------------------------
HINSTANCE hHID = NULL;
PHidD_GetProductString HidD_GetProductString = NULL;
PHidD_GetHidGuid HidD_GetHidGuid = NULL;
PHidD_GetAttributes HidD_GetAttributes = NULL;
PHidD_SetFeature HidD_SetFeature = NULL;
PHidD_GetFeature HidD_GetFeature = NULL;
HANDLE DeviceHandle = INVALID_HANDLE_VALUE;
unsigned int moreHIDDevices=TRUE;
unsigned int HIDDeviceFound=FALSE;
unsigned int terminaAbruptaEInstantaneamenteElPrograma=0;
void Load_HID_Library (void) {
hHID = LoadLibrary("HID.DLL");
if (!hHID) {
printf("Failed to load HID.DLL\n");
return;
}
HidD_GetProductString = (PHidD_GetProductString) GetProcAddress(hHID, "HidD_GetProductString");
HidD_GetHidGuid = (PHidD_GetHidGuid) GetProcAddress(hHID, "HidD_GetHidGuid");
HidD_GetAttributes = (PHidD_GetAttributes) GetProcAddress(hHID, "HidD_GetAttributes");
HidD_SetFeature = (PHidD_SetFeature) GetProcAddress(hHID, "HidD_SetFeature");
HidD_GetFeature = (PHidD_GetFeature) GetProcAddress(hHID, "HidD_GetFeature");
if ( !HidD_GetProductString
|| !HidD_GetAttributes
|| !HidD_GetHidGuid
|| !HidD_SetFeature
|| !HidD_GetFeature ) {
printf("Couldn't find one or more HID entry points\n");
return;
}
}
int Open_Device(void) {
HDEVINFO DeviceInfoSet;
GUID InterfaceClassGuid;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData;
HIDD_ATTRIBUTES Attributes;
DWORD Result;
DWORD MemberIndex = 0;
DWORD Required;
//Validar si se "cargó" la biblioteca (DLL)
if (!hHID)
return (0);
//Obtener el Globally Unique Identifier (GUID) para dispositivos HID
HidD_GetHidGuid (&InterfaceClassGuid);
//Sacarle a Windows la información sobre todos los dispositivos HID instalados y activos en el sistema
// ... almacenar esta información en una estructura de datos de tipo HDEVINFO
DeviceInfoSet = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
if (DeviceInfoSet == INVALID_HANDLE_VALUE)
return (0);
//Obtener la interfaz de comunicación con cada uno de los dispositivos para preguntarles información específica
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
while (!HIDDeviceFound) {
// ... utilizando la variable MemberIndex ir preguntando dispositivo por dispositivo ...
moreHIDDevices = SetupDiEnumDeviceInterfaces (DeviceInfoSet, NULL, &InterfaceClassGuid,
MemberIndex,&DeviceInterfaceData);
if (!moreHIDDevices) {
// ... si llegamos al fin de la lista y no encontramos al dispositivo ==> terminar y marcar error
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return (0); //No more devices found
} else {
//Necesitamos preguntar, a través de la interfaz, el PATH del dispositivo, para eso ...
// ... primero vamos a ver cuántos caracteres se requieren (Required)
Result = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,&DeviceInterfaceData,NULL,0,&Required,NULL);
pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Required);
if (pDeviceInterfaceDetailData == NULL) {
printf("Error en SetupDiGetDeviceInterfaceDetail\n");
return (0);
}
//Ahora si, ya que el "buffer" fue preparado (pDeviceInterfaceDetailData{DevicePath}), vamos a preguntar PATH
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
Result = SetupDiGetDeviceInterfaceDetail (DeviceInfoSet,&DeviceInterfaceData,pDeviceInterfaceDetailData,
Required,NULL,NULL);
if (!Result) {
printf("Error en SetupDiGetDeviceInterfaceDetail\n");
free(pDeviceInterfaceDetailData);
return(0);
}
//Para este momento ya sabemos el PATH del dispositivo, ahora hay que preguntarle ...
// ... su VID y PID, para ver si es con quien nos interesa comunicarnos
printf("Found? ==> ");
printf("Device: %s\n",pDeviceInterfaceDetailData->DevicePath);
//Obtener un "handle" al dispositivo
DeviceHandle = CreateFile (pDeviceInterfaceDetailData->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
if (DeviceHandle == INVALID_HANDLE_VALUE) {
printf("¡¡¡Error en el CreateFile!!!\n");
} else {
//Preguntar por los atributos del dispositivo
Attributes.Size = sizeof(Attributes);
Result = HidD_GetAttributes (DeviceHandle,&Attributes);
if (!Result) {
printf("Error en HIdD_GetAttributes\n");
CloseHandle(DeviceHandle);
free(pDeviceInterfaceDetailData);
return(0);
}
//Analizar los atributos del dispositivo para verificar el VID y PID
printf("MemberIndex=%d,VID=%04x,PID=%04x\n",MemberIndex,Attributes.VendorID,Attributes.ProductID);
if ((Attributes.VendorID == RICH_VENDOR_ID) && (Attributes.ProductID == RICH_USBHID_GENIO_ID)) {
printf("USB/HID GenIO ==> ");
printf("Device: %s\n",pDeviceInterfaceDetailData->DevicePath);
HIDDeviceFound=TRUE;
} else
CloseHandle(DeviceHandle);
}
MemberIndex++;
free(pDeviceInterfaceDetailData);
if (HIDDeviceFound) {
printf("Dispositivo HID solicitado ... ¡¡¡localizado!!!, presione <ENTER>\n");
getchar();
}
}
}
return(1);
}
void Close_Device (void) {
if (DeviceHandle != NULL) {
CloseHandle(DeviceHandle);
DeviceHandle = NULL;
}
}
int chToIndex(unsigned char ch){
if((ch>='0')&&(ch<='9')){
return ch-48;
}else if((ch>='A')&&(ch<='Z')){
return ch-55;
}else if((ch>='a')&&(ch<='z')){
return ch-61;
}else{
switch (ch){
case '*': return 62;
// break;
case '+': return 63;
// break;
case '-': return 64;
//break;
case '/': return 65;
//break;
case '=': return 66;
// break;
case '>': return 67;
// break;
case '<': return 68;
// break;
case '!': return 69;
// break;
case '.': return 70;
// break;
case '&': return 71;
// break;
case '^': return 72;
// break;
case '(': return 73;
// break;
case ')': return 74;
// break;
case '[': return 75;
// break;
case ']': return 76;
// break;
case ',': return 77;
// break;
case ';': return 78;
// break;
case ':': return 79;
// break;
case 0x20: return 80;
default: return 81;
// break;
}
}
}
int Touch_Device (void) {
int z;
int index;
int col,lin;
unsigned char ch;
if (DeviceHandle == NULL) //Validar que haya comunicacion con el dispositivo
return 0;
if(c != '27' )
{
printf("Selecciona accion:\n1) Limpiar Pantalla\n2) Imprimir todos caracteres\n3) Escribir caracter\n4) Escribir string\n5) Salir\n");
desplegar=getch();
desplegar=getch();
if((desplegar=='5')||(desplegar==(char)'27')){
terminaAbruptaEInstantaneamenteElPrograma=1;
}
else if(desplegar=='4'){
lin=0;
col=0;
index=0;
printf("Escribe texto (termina con Enter):\n");
scanf("%s",palabra);
while(palabra[index]!='\0'){
z++;
}
printf("Longitud de palabra: %d",z);
while((palabra[index]!='\0')){
if((palabra[index]==NULL)&&(palabra[index+1]!=NULL))
palabra[index]=0x20;
reporteSalida[0]=0x00;
reporteSalida[1]=0x04;
reporteSalida[2]=(char)chToIndex(palabra[index]);
reporteSalida[3]=(char)lin;
reporteSalida[4]=(char)col;
status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
if (!status)
printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
else
printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);
if(col>=23){
lin++;
col=0;
}
if(lin>=7){
lin=0;
}
col++;
index++;
}
}
else if (desplegar=='3'){
reporteSalida[0]=0x00;
reporteSalida[1]=0x04;
printf("Que caracter deseas desplegar: ");
ch=getch();
printf("\n");
z=chToIndex(ch);
reporteSalida[2]=(char)z;
do{
printf("En que renglon en y (0-7): ");
scanf("%d",&desplegar);
printf("\n");
}while((desplegar<0)&&(desplegar>7));
reporteSalida[3]=(char)desplegar;
do{
printf("En que columna en x (0-23): ");
scanf("%d",&desplegar);
printf("\n");
}while((desplegar<0)&&(desplegar>23));
reporteSalida[4]=(char)desplegar;
printf("ReporteSalida: %02X %02X %02X %02X %02X \n",(unsigned char)reporteSalida[0],
(unsigned char)reporteSalida[1],
(unsigned char)reporteSalida[2],
(unsigned char)reporteSalida[3],
(unsigned char)reporteSalida[4]);
status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
if (!status)
printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
else
printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);
}
else if (desplegar=='2'){
lin=0;
col=0;
for (index=0;index<=80;index++){
reporteSalida[0]=0x00;
reporteSalida[1]=0x04;
reporteSalida[2]=(char)index;
reporteSalida[3]=(char)lin;
reporteSalida[4]=(char)col;
status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
if (!status)
printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
else
printf("Se enviaron %d bytes al dispositivo (posX=%d, posY=%d, dato=%d)\n",BytesWritten,reporteSalida[4],reporteSalida[3],reporteSalida[2]);
if(col>=23){
lin++;
col=0;
}
if(lin>=7){
lin=0;
}
col++;
}
}
else if(desplegar=='1'){
printf("Limpiando pantalla ...\n");
reporteSalida[0]=0x00;
reporteSalida[1]=0x03;
reporteSalida[2]=0;
status = WriteFile(DeviceHandle,reporteSalida,INPUT_REPORT_SIZE+1,&BytesWritten,NULL);
if (!status)
printf("Error en el WriteFile %d %d\n",GetLastError(),BytesWritten);
else
printf("Escritos %d\n",BytesWritten);
}
else{
Touch_Device();
}
}
return status;
}
void main () {
Load_HID_Library();
if (Open_Device()) {
printf("Vamos bien\n");
while ((c=getch()!=27)
&&(!terminaAbruptaEInstantaneamenteElPrograma)) {
Touch_Device();
Sleep(500);
}
} else {
printf(">:(\n");
}
Close_Device();
}
最佳答案
总的来说,您可以将任何 C 代码编译为 C++。您是否尝试将其编译为 C++,是否遇到任何错误?
您的问题的答案是,是的,您可以像使用 C 一样使用 C++ 中的 SETUPAPI.DLL 和 HID.DLL。
关于c++ - HID 设备编程 - 它是否适用于 C++(SETUPAPI.dll 和 HID.dll),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10393237/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!