混合DotNet与Win32API来实现的Hidlibrary,c/c++可直接使用,c#可直接使用

异步IO,拔插事件订阅,数据读取事件订阅


工程目录结构

  1. HidEvent.h
  1. #pragma once
  2.  
  3. typedef void (*HidEvent)();
  4. typedef void (__cdecl *HidReadDataEvent)(unsigned char *data, int len);
  1. Hidimpl.h
  1. #pragma once
  2. #include "HidEvent.h"
  3.  
  4. class Hidimpl
  5. {
  6. public:
  7. Hidimpl(int vid, int pid);
  8. ~Hidimpl(void);
  9.  
  10. bool FindMyDevice();
  11. void NotifyEvents(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
  12.  
  13. int getInputLen()
  14. {
  15. return mInputLen;
  16. }
  17.  
  18. int getOutputLen()
  19. {
  20. return mOutputLen;
  21. }
  22.  
  23. bool IsConnected()
  24. {
  25. return mIsConnected;
  26. }
  27.  
  28. public:
  29. // IO Functions
  30. //int Read(unsigned char *data, int len);
  31. void Write(unsigned char *data, int len);
  32.  
  33. public:
  34. static Hidimpl *mTarget;
  35. static DWORD ThreadMessageRoutine(LPVOID lparam);
  36. static LRESULT CALLBACK ZSHidWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
  37.  
  38. public:
  39. HidEvent mArrivalEvent;
  40. HidEvent mRemovedEvent;
  41. HidReadDataEvent mReadDataEvent;
  42.  
  43. private:
  44. void MyDeviceRemoved();
  45.  
  46. private:
  47. int mInputLen;
  48. int mOutputLen;
  49. bool mIsConnected;
  50.  
  51. int mVid;
  52. int mPid;
  53. HANDLE mhHidRx;
  54. HANDLE mhHidTx;
  55.  
  56. DWORD mThreadId;
  57. HANDLE mThreadHandle;
  58.  
  59. // Managed objects FileStream
  60. void *mFsRx;
  61. void *mFsTx;
  62. };
  1. Hidimpl.cpp
  1. #include "StdAfx.h"
  2. #include "Hidimpl.h"
  3. #include "HidState.h"
  4. #include <vcclr.h>
  5.  
  6. #pragma comment(lib, "hid.lib")
  7. #pragma comment(lib, "setupapi.lib")
  8.  
  9. using namespace System;
  10. using namespace System::IO;
  11. using namespace Microsoft::Win32::SafeHandles;
  12.  
  13. Hidimpl *Hidimpl::mTarget = nullptr;
  14.  
  15. Hidimpl::Hidimpl(int vid, int pid)
  16. :mFsRx(nullptr), mFsTx(nullptr),
  17. mArrivalEvent(nullptr), mRemovedEvent(nullptr),
  18. mThreadId(), mThreadHandle(INVALID_HANDLE_VALUE)
  19. {
  20. mVid = vid;
  21. mPid = pid;
  22.  
  23. FindMyDevice();
  24. }
  25.  
  26. Hidimpl::~Hidimpl(void)
  27. {
  28. MyDeviceRemoved();
  29. if (mThreadHandle != INVALID_HANDLE_VALUE)
  30. {
  31. PostThreadMessage(mThreadId, WM_CLOSE, , );
  32. mThreadHandle = INVALID_HANDLE_VALUE;
  33. }
  34. }
  35.  
  36. void Hidimpl::MyDeviceRemoved()
  37. {
  38. if (mFsRx)
  39. {
  40. gcroot<FileStream ^> *_pfs = static_cast<gcroot<FileStream ^> *>(mFsRx);
  41. // not need only delete ok
  42. //((FileStream ^)*_pfs)->Close();
  43. delete _pfs;
  44. mFsRx = nullptr;
  45. }
  46.  
  47. if (mFsTx)
  48. {
  49. gcroot<FileStream ^> *_pfs = static_cast<gcroot<FileStream ^> *>(mFsTx);
  50. // not need only delete ok
  51. //((FileStream ^)*_pfs)->Close();
  52. delete _pfs;
  53. mFsTx = nullptr;
  54. }
  55.  
  56. // 不需要手动关闭GC自动处理
  57. // this is also a crazy fucking shit
  58. // 关闭的句柄被重复关闭会引发[0xC0000008: An invalid handle was specified]
  59. //CloseHandle(mhHidRx);
  60. //mhHidRx = INVALID_HANDLE_VALUE;
  61. //CloseHandle(mhHidTx);
  62. //mhHidTx = INVALID_HANDLE_VALUE;
  63. }
  64.  
  65. bool Hidimpl::FindMyDevice()
  66. {
  67. bool isFind = false;
  68. GUID guid;
  69. HidD_GetHidGuid(&guid);
  70. HDEVINFO hdevinfo = SetupDiGetClassDevs(&guid, , , DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
  71. SP_DEVICE_INTERFACE_DATA device_interface_data;
  72. ZeroMemory(&device_interface_data, sizeof(device_interface_data));
  73. device_interface_data.cbSize = sizeof(device_interface_data);
  74.  
  75. int device_interface_index = ;
  76. while (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, &guid, device_interface_index, &device_interface_data))
  77. {
  78. DWORD requireSize;
  79. SetupDiGetDeviceInterfaceDetail(hdevinfo, &device_interface_data, NULL, , &requireSize, NULL);
  80. PSP_DEVICE_INTERFACE_DETAIL_DATA psp_device_interface_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requireSize);
  81. psp_device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  82. if (SetupDiGetDeviceInterfaceDetail(hdevinfo, &device_interface_data, psp_device_interface_detail_data, requireSize, &requireSize, NULL))
  83. {
  84. TCHAR *device_path = psp_device_interface_detail_data->DevicePath;
  85.  
  86. // 打印设备路径[将TCHAR *转换为System::String^]
  87. //String ^str_path = gcnew String(device_path);
  88. //Console::ForegroundColor = ConsoleColor::Blue;
  89. //Console::WriteLine(str_path);
  90. //Console::ResetColor();
  91.  
  92. HANDLE handle = CreateFile(device_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
  93. if (handle != INVALID_HANDLE_VALUE)
  94. {
  95. HIDD_ATTRIBUTES hidd_attributes;
  96. HidD_GetAttributes(handle, &hidd_attributes);
  97. if (hidd_attributes.VendorID == mVid && hidd_attributes.ProductID == mPid)
  98. {
  99. PHIDP_PREPARSED_DATA phidp_preparsed_data;
  100. HidD_GetPreparsedData(handle, &phidp_preparsed_data);
  101. HIDP_CAPS hidp_caps;
  102. HidP_GetCaps(phidp_preparsed_data, &hidp_caps);
  103. mInputLen = hidp_caps.InputReportByteLength;
  104. mOutputLen = hidp_caps.OutputReportByteLength;
  105. HidD_FreePreparsedData(phidp_preparsed_data);
  106.  
  107. // 打印设备路径[将TCHAR *转换为System::String^]
  108. String ^str_path = gcnew String(device_path);
  109. Console::ForegroundColor = ConsoleColor::Green;
  110. Console::WriteLine(str_path);
  111. Console::ResetColor();
  112.  
  113. mhHidRx = CreateFile(device_path, GENERIC_READ,
  114. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  115. mhHidTx = CreateFile(device_path, GENERIC_WRITE,
  116. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  117.  
  118. SafeFileHandle ^_hRx = gcnew SafeFileHandle((IntPtr)mhHidRx, true);
  119. FileStream ^_fsRx = gcnew FileStream(_hRx, FileAccess::Read, mInputLen, true);
  120. // managed type conversion into unmanaged pointer is not allowed.
  121. // we can use gcroot<> wrapper
  122. gcroot<FileStream^> *_pfs = new gcroot<FileStream ^>(_fsRx);
  123. mFsRx = static_cast<void *>(_pfs);
  124.  
  125. SafeFileHandle ^_hTx = gcnew SafeFileHandle((IntPtr)mhHidTx, true);
  126. FileStream ^_fsTx = gcnew FileStream(_hTx, FileAccess::Write, mOutputLen, true);
  127. // managed type conversion into unmanaged pointer is not allowed.
  128. // we can use gcroot<> wrapper
  129. _pfs = new gcroot<FileStream^>(_fsTx);
  130. mFsTx = static_cast<void *>(_pfs);
  131.  
  132. HidState ^state = gcnew HidState(this, _fsRx, mInputLen);
  133. _fsRx->BeginRead(state->mBuffer, , state->mBuffer->Length, gcnew AsyncCallback(state, &HidState::EndRead), state);
  134.  
  135. isFind = true;
  136. CloseHandle(handle);
  137. free(psp_device_interface_detail_data);
  138. break;
  139. }
  140.  
  141. CloseHandle(handle);
  142. }
  143. }
  144. else
  145. {
  146. int error = GetLastError();
  147. Console::ForegroundColor = ConsoleColor::Blue;
  148. Console::WriteLine("[SetupDiGetDeviceInterfaceDetail Error]GetLastError = " + error);
  149. Console::ResetColor();
  150. }
  151.  
  152. device_interface_index++;
  153. free(psp_device_interface_detail_data);
  154. }
  155.  
  156. SetupDiDestroyDeviceInfoList(hdevinfo);
  157. mIsConnected = isFind;
  158.  
  159. return isFind;
  160. }
  161.  
  162. void Hidimpl::NotifyEvents(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata)
  163. {
  164. // Cannt reset event to device
  165. if (mThreadHandle != INVALID_HANDLE_VALUE) return;
  166.  
  167. mArrivalEvent = arrival;
  168. mRemovedEvent = removed;
  169. mReadDataEvent = rdata;
  170.  
  171. mThreadHandle = CreateThread(NULL, ,
  172. (LPTHREAD_START_ROUTINE)ThreadMessageRoutine, this, THREAD_PRIORITY_NORMAL, &mThreadId);
  173. }
  174.  
  175. DWORD Hidimpl::ThreadMessageRoutine(LPVOID lparam)
  176. {
  177. mTarget = static_cast<Hidimpl *>(lparam);
  178. HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(NULL));
  179.  
  180. WNDCLASS wndClass = {};
  181. wndClass.lpfnWndProc = ZSHidWndProc;
  182. wndClass.lpszClassName = L"ZSHidlib";
  183. wndClass.hInstance = hInstance;
  184. if (RegisterClass(&wndClass))
  185. {
  186. // 为线程消息循环(HWND_MESSAGE)
  187. HWND hwnd = CreateWindowEx(, wndClass.lpszClassName, NULL,
  188. , , , , , HWND_MESSAGE, NULL, hInstance, NULL);
  189. if (hwnd != INVALID_HANDLE_VALUE)
  190. {
  191. GUID guid;
  192. HidD_GetHidGuid(&guid);
  193. DEV_BROADCAST_DEVICEINTERFACE notifycationFilter = {};
  194. notifycationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
  195. notifycationFilter.dbcc_classguid = guid;
  196. notifycationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  197. HDEVNOTIFY hdevnotify = RegisterDeviceNotification(hwnd, &notifycationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
  198.  
  199. if (hdevnotify != INVALID_HANDLE_VALUE)
  200. {
  201. Console::ForegroundColor = ConsoleColor::Blue;
  202. Console::WriteLine("Notify注册成功,即将进入消息循环.");
  203. Console::ResetColor();
  204.  
  205. MSG msg;
  206. if (GetMessage(&msg, NULL, , ) > )
  207. {
  208. TranslateMessage(&msg);
  209. DispatchMessage(&msg);
  210. }
  211. }
  212.  
  213. Console::ForegroundColor = ConsoleColor::Blue;
  214. Console::WriteLine("退出消息循环........................");
  215. Console::ResetColor();
  216.  
  217. UnregisterDeviceNotification(hdevnotify);
  218. DestroyWindow(hwnd);
  219. UnregisterClass(wndClass.lpszClassName, hInstance);
  220. }
  221. }
  222.  
  223. return ;
  224. }
  225.  
  226. LRESULT CALLBACK Hidimpl::ZSHidWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  227. {
  228. if (msg == WM_DEVICECHANGE)
  229. {
  230. switch (wparam)
  231. {
  232. case DBT_DEVICEARRIVAL:
  233. {
  234. if (!mTarget->mIsConnected)
  235. {
  236. if (mTarget->FindMyDevice())
  237. {
  238. Console::ForegroundColor = ConsoleColor::Blue;
  239. Console::WriteLine("MY HID DEVICE IS FOUND AND OPEN.");
  240. Console::ResetColor();
  241.  
  242. // My device arrival event
  243. if (mTarget->mArrivalEvent != nullptr)
  244. mTarget->mArrivalEvent();
  245. }
  246. }
  247. }
  248. break;
  249. case DBT_DEVICEREMOVECOMPLETE:
  250. {
  251. if (mTarget->mIsConnected)
  252. {
  253. if (!mTarget->FindMyDevice())
  254. {
  255. Console::ForegroundColor = ConsoleColor::Blue;
  256. Console::WriteLine("MY HID DEVICE REMOVED.");
  257. Console::ResetColor();
  258.  
  259. // My device remove event
  260. mTarget->MyDeviceRemoved();
  261. if (mTarget->mRemovedEvent != nullptr)
  262. mTarget->mRemovedEvent();
  263. }
  264. }
  265. }
  266. break;
  267. default:
  268. break;
  269. }
  270. }
  271.  
  272. return DefWindowProc(hwnd, msg, wparam, lparam);
  273. }
  274.  
  275. void Hidimpl::Write(unsigned char *data, int len)
  276. {
  277. if (!mIsConnected) return;
  278. array<unsigned char> ^_data = gcnew array<unsigned char>(mOutputLen);
  279. try
  280. {
  281. int length = len>mOutputLen?mOutputLen:len;
  282. for (int i = ; i < length; i++) _data[i] = data[i];
  283.  
  284. if (mFsTx != nullptr)
  285. {
  286. gcroot<FileStream^> *_pfs = static_cast<gcroot<FileStream^> *>(mFsTx);
  287. //((FileStream^)*_pfs)->Write(_data, 0, _data->Length);
  288. ((FileStream^)*_pfs)->BeginWrite(_data, , _data->Length, nullptr, nullptr);
  289. ((FileStream^)*_pfs)->Flush();
  290. }
  291. }
  292. catch(IOException ^e)
  293. {
  294. Console::WriteLine(e->Message);
  295. }
  296. catch(Exception ^e)
  297. {
  298. Console::WriteLine(e->Message);
  299. }
  300. }
  1. HidState.h
  1. #pragma once
  2. #include "Hidimpl.h"
  3.  
  4. using namespace System;
  5. using namespace System::IO;
  6.  
  7. public ref class HidState
  8. {
  9. public:
  10. HidState(Hidimpl *hid, FileStream ^fs, int bufferLen);
  11. ~HidState();
  12. void EndRead(IAsyncResult ^ar);
  13.  
  14. public:
  15. Hidimpl *mHidimpl;
  16. FileStream ^mFileStream;
  17. array<unsigned char> ^mBuffer;
  18. };
  1. HidState.cpp
  1. #include "stdafx.h"
  2. #include "HidState.h"
  3.  
  4. HidState::HidState(Hidimpl *hid, FileStream ^fs, int bufferLen)
  5. {
  6. mHidimpl = hid;
  7. mFileStream = fs;
  8. mBuffer = gcnew array<unsigned char>(bufferLen);
  9. }
  10.  
  11. HidState::~HidState()
  12. {
  13. mHidimpl = nullptr;
  14. }
  15.  
  16. void HidState::EndRead(IAsyncResult ^ar)
  17. {
  18. HidState ^state = dynamic_cast<HidState ^>(ar->AsyncState);
  19. try
  20. {
  21. int count = state->mFileStream->EndRead(ar);
  22. // [有数据读入的情况下]调用ReadData事件
  23. if (mHidimpl->mReadDataEvent != nullptr && count > )
  24. {
  25. unsigned char *ptrdt = new unsigned char[count];
  26. for (int i = ; i < count; i++) ptrdt[i] = mBuffer[i];
  27. // 此处封送到C#的IntPtr指针(this a crazy fucking)
  28. mHidimpl->mReadDataEvent(ptrdt, count);
  29. delete []ptrdt;
  30. }
  31. if (mHidimpl->IsConnected())
  32. state->mFileStream->BeginRead(state->mBuffer, , mBuffer->Length, gcnew AsyncCallback(this, &HidState::EndRead), state);
  33. }
  34. catch(IOException ^e)
  35. {
  36. Console::WriteLine(e->Message);
  37. }
  38. catch(Exception ^e)
  39. {
  40. Console::WriteLine(e->Message);
  41. }
  42. }

_______export,wrap managed clr class for csharp

  1. Hidlib.h
  1. #pragma once
  2. #include "Hidimpl.h"
  3.  
  4. using namespace System;
  5.  
  6. public ref class Hidlib
  7. {
  8. public:
  9. delegate void HidDelegate();
  10. delegate void HidReadDataDelegate(IntPtr data, int len);
  11.  
  12. public:
  13. Hidlib(int vid, int pid);
  14. void NotifyEvents(HidDelegate ^arrival, HidDelegate ^removed, HidReadDataDelegate ^rdata);
  15. void Write(array<unsigned char> ^data);
  16.  
  17. private:
  18. Hidimpl *impl;
  19. };
  1. Hidlib.cpp  
  1. #include "stdafx.h"
  2. #include "Hidlib.h"
  3. #include <vcclr.h>
  4.  
  5. using namespace System::IO;
  6. using namespace System::Runtime::InteropServices;
  7.  
  8. Hidlib::Hidlib(int vid, int pid)
  9. {
  10. impl = new Hidimpl(vid, pid);
  11. }
  12.  
  13. void Hidlib::NotifyEvents(HidDelegate ^arrival, HidDelegate ^removed, HidReadDataDelegate ^rdata)
  14. {
  15. IntPtr _arrival = Marshal::GetFunctionPointerForDelegate(arrival);
  16. IntPtr _removed = Marshal::GetFunctionPointerForDelegate(removed);
  17. IntPtr _rdata = Marshal::GetFunctionPointerForDelegate(rdata);
  18. impl->NotifyEvents((HidEvent)_arrival.ToPointer(), (HidEvent)_removed.ToPointer(), (HidReadDataEvent)_rdata.ToPointer());
  19. }
  20.  
  21. void Hidlib::Write(array<unsigned char> ^data)
  22. {
  23. try
  24. {
  25. int length = data->Length>impl->getOutputLen()?impl->getOutputLen():data->Length;
  26. if (impl->mFsTx != nullptr)
  27. {
  28. gcroot<FileStream^> *_pfs = static_cast<gcroot<FileStream^> *>(impl->mFsTx);
  29. //((FileStream^)*_pfs)->Write(_data, 0, _data->Length);
  30. ((FileStream^)*_pfs)->BeginWrite(data, , length, nullptr, nullptr);
  31. ((FileStream^)*_pfs)->Flush();
  32. }
  33. }
  34. catch(IOException ^e)
  35. {
  36. Console::WriteLine(e->Message);
  37. }
  38. catch(Exception ^e)
  39. {
  40. Console::WriteLine(e->Message);
  41. }
  42. }
  • 提供PInvoke接口
  1. PInvoke(平台调用)
  1. #pragma once
  2. #include <Hidimpl.h>
  3. #include "HidEvent.h"
  4.  
  5. #ifdef ZSHIDLIB_EXPORTS
  6. #define ZSHIDLIB_API __declspec(dllexport)
  7. #else
  8. #define ZSHIDLIB_API __declspec(dllimport)
  9. #endif
  10.  
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. ZSHIDLIB_API void Open(int vid, int pid);
  15. ZSHIDLIB_API bool IsOpen();
  16. ZSHIDLIB_API bool IsConnected();
  17. ZSHIDLIB_API int getInputLen();
  18. ZSHIDLIB_API int getOutputLen();
  19. ZSHIDLIB_API void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
  20. ZSHIDLIB_API void Write(unsigned char *data, int len);
  21. ZSHIDLIB_API void Close();
  22. #ifdef __cplusplus
  23. };
  24. #endif
  1. #include "stdafx.h"
  2. #include "Hidlib.h"
  3. #include "Hidimpl.h"
  4.  
  5. Hidimpl *pHidimpl = nullptr;
  6.  
  7. ZSHIDLIB_API void Open(int vid, int pid)
  8. {
  9. if (pHidimpl == nullptr)
  10. pHidimpl = new Hidimpl(vid, pid);
  11. }
  12.  
  13. ZSHIDLIB_API bool IsOpen()
  14. {
  15. return (pHidimpl != nullptr);
  16. }
  17.  
  18. ZSHIDLIB_API bool IsConnected()
  19. {
  20. if (pHidimpl != nullptr)
  21. return pHidimpl->IsConnected();
  22.  
  23. return ;
  24. }
  25.  
  26. ZSHIDLIB_API int getInputLen()
  27. {
  28. if (pHidimpl != nullptr)
  29. return pHidimpl->getInputLen();
  30.  
  31. return ;
  32. }
  33.  
  34. ZSHIDLIB_API int getOutputLen()
  35. {
  36. if (pHidimpl != nullptr)
  37. return pHidimpl->getOutputLen();
  38.  
  39. return ;
  40. }
  41.  
  42. ZSHIDLIB_API void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata)
  43. {
  44. if (pHidimpl != nullptr)
  45. {
  46. pHidimpl->NotifyEvents(arrival, removed, rdata);
  47. }
  48. }
  49.  
  50. ZSHIDLIB_API void Write(unsigned char *data, int len)
  51. {
  52. if (pHidimpl != nullptr)
  53. pHidimpl->Write(data, len);
  54. }
  55.  
  56. ZSHIDLIB_API void Close()
  57. {
  58. if (pHidimpl != nullptr)
  59. {
  60. delete pHidimpl;
  61. pHidimpl = nullptr;
  62. }
  63. }
  • C#中的使用
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace ZSHidApp
  8. {
  9. delegate void HidEvent();
  10. delegate void HidReadDataEvent(IntPtr data, int len);
  11.  
  12. class Program
  13. {
  14. //[DllImport("ZSHidlib.dll")]
  15. //public static extern void Open(int vid, int pid);
  16.  
  17. //[DllImport("ZSHidlib.dll")]
  18. //public static extern void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
  19.  
  20. //[DllImport("ZSHidlib.dll")]
  21. //public static extern void Write(Byte[] data, int len);
  22.  
  23. //[DllImport("ZSHidlib.dll")]
  24. //public static extern void GetData(ref Byte[] data, int len);
  25.  
  26. static void ReadData(IntPtr data, int len)
  27. {
  28. Byte[] _data = new Byte[len];
  29. Marshal.Copy(data, _data, , len);
  30.  
  31. // Log
  32. Console.WriteLine("// usr subscription //_____________________________________");
  33. for (int i = ; i < _data.Length; i++) Console.Write(string.Format("{0:x2} ", _data[i]));
  34. Console.WriteLine();
  35. }
  36.  
  37. static void Main(string[] args)
  38. {
  39. //Open(0x0b6a, 0x5346);
  40. //Notify(() => Console.WriteLine("______________device arrival."),
  41. // () => Console.WriteLine("__________________device removed."),
  42. // ReadData);
  43. Hidlib hidlib = new Hidlib(0x0b6a, 0x5346);
  44. hidlib.NotifyEvents(() => Console.WriteLine("______________device arrival."),
  45. () => Console.WriteLine("__________________device removed."),
  46. ReadData);
  47.  
  48. while (true)
  49. {
  50. ConsoleKeyInfo keyInfo = Console.ReadKey();
  51. if (keyInfo.Key == ConsoleKey.Q)
  52. {
  53. break;
  54. }
  55. else if (keyInfo.Key == ConsoleKey.W)
  56. {
  57. Byte[] buffer = new Byte[];
  58. // ab 69 42 01 fe aa 00 00 aa cd
  59. int i = ;
  60. buffer[i++] = ;
  61. buffer[i++] = 0xab;
  62. buffer[i++] = 0x69;
  63. buffer[i++] = 0x42;
  64. buffer[i++] = 0x01;
  65. buffer[i++] = 0xfe;
  66. buffer[i++] = 0xaa;
  67. buffer[i++] = 0x00;
  68. buffer[i++] = 0x00;
  69. buffer[i++] = 0xaa;
  70. buffer[i++] = 0xcd;
  71. hidlib.Write(buffer);
  72. }
  73. }
  74. }
  75. }
  76. }
  • Standard C++中的使用
  1. // ZSHidWin32App.cpp : 定义控制台应用程序的入口点。
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "../ZSHidlib/Hidlib.h"
  6. #include "../ZSHidlib/Hidimpl.h"
  7.  
  8. #pragma comment(lib, "../Debug/ZSHidlib.lib")
  9.  
  10. void Arrival()
  11. {
  12. printf("______________________device arrival.\n");
  13. }
  14.  
  15. void Removed()
  16. {
  17. printf("______________________device removed.\n");
  18. }
  19.  
  20. void ReadData(unsigned char *data, int len)
  21. {
  22. for (int i = ; i < len; i++)
  23. {
  24. printf("%.2x ", data[i]);
  25. }
  26. printf("___________________call in ReadData callback function.");
  27. }
  28.  
  29. int _tmain(int argc, _TCHAR* argv[])
  30. {
  31. Hidimpl *hidImpl = new Hidimpl(0x0b6a, 0x5346);
  32. hidImpl->NotifyEvents(Arrival, Removed, ReadData);
  33.  
  34. while(true)
  35. {
  36. unsigned char buffer[] = {0x00, 0xab, 0x69, 0x42, 0x01, 0xfe, 0xaa, 0x00, 0x00, 0xaa, 0xcd};
  37. hidImpl->Write(buffer, );
  38.  
  39. Sleep();
  40. }
  41.  
  42. system("pause");
  43.  
  44. return ;
  45. }

  • 参考书籍/资料

  《Visual C++/CLI从入门到精通》

《NET互操作 P_Invoke,C++Interop和COM Interop》


c++/cli mixed codes for standard c++ and csharp的更多相关文章

  1. 关于aws cli命令的exit/return code分析

    最近总是收到一个备份脚本的失败邮件,脚本是之前同事写的,没有加入任何有调试信息,及有用的日志 于是去分析 ,脚本中有一条 aws s3 sync $srclocal  $dsts3 命令,然后根据这条 ...

  2. Go 语言相关的优秀框架,库及软件列表

    If you see a package or project here that is no longer maintained or is not a good fit, please submi ...

  3. Awesome Go精选的Go框架,库和软件的精选清单.A curated list of awesome Go frameworks, libraries and software

    Awesome Go      financial support to Awesome Go A curated list of awesome Go frameworks, libraries a ...

  4. $geoNear

    怎么使用mongoose的geoNear 2014-11-26 15:05:20|  分类: mongodb |  标签:mongoose  |举报|字号 订阅     下载LOFTER我的照片书   ...

  5. mongodb的地理位置索引

    mongoDB支持二维空间索引,使用空间索引,mongoDB支持一种特殊查询,如某地图网站上可以查找离你最近的咖啡厅,银行等信息.这个使用mongoDB的空间索引结合特殊的查询方法很容易实现.前提条件 ...

  6. Transparency Tutorial with C# - Part 1

    Download demo project - 4 Kb Download source - 6 Kb Download demo project - 5 Kb Download source - 6 ...

  7. Awesome Go

    A curated list of awesome Go frameworks, libraries and software. Inspired by awesome-python. Contrib ...

  8. CFA一级知识点总结

    更多来自:   www.vipcoursea.com   Ethics 部分 Objective of codes and standard:永远是为了maintain public trust in ...

  9. 从早期 Spring Boot 版本升级

    如果你现在正在从早期的 Spring Boot 版本进行升级的话,请访问 “migration guide” on the project wiki 页面,这个页面提供了有关升级的详细指南.同时也请查 ...

随机推荐

  1. [USACO19OPEN]Valleys P

    题意 洛谷 做法 用并查集维护区域,剩下的就只用判是否有洞就好了 然后手玩出一个结论:凸角为\(+1\),凹角为\(-1\),和为\(sum\),洞数\(h\),满足\(sum=4-4h\) 位置\( ...

  2. 【sklearn】Toy datasets上的分类/回归问题 (XGBoost实践)

    分类问题 1. 手写数字识别问题 from sklearn.datasets import load_digits digits = load_digits() # 加载手写字符识别数据集 X = d ...

  3. Java出现次数最多的整数

    描述 编写一个程序,读入一组整数,这组整数是按照从小到大的顺序排列的,它们的个数N也是由用户输入的,最多不会超过20.然后程序将对这个数组进行统计,把出现次数最多的那个数组元素值打印出来.如果有两个元 ...

  4. 【Spring】事务(transactional)之初步理解

    一. 场景 有一个定时器,做数据库表数据同步. 把数据库A的表table(DB_A_TABLE)同步到数据库B的表table(DB_B_TABLE). 对于DB_A_TABLE的每行数据要做一定的逻辑 ...

  5. win10家庭版更改本地账户名、C盘Users下文件夹名和环境变量等

    PS:由于四五年前装系统的时候懵懵懂懂的敲了一个中文用户名(有一个字还打错了,尴尬),导致现在打开cmd默认是C:\Users\中文名,path环境变量中也有中文路径,有时候有些程序的路径也是中文,这 ...

  6. Java代码中特殊注释

    Java代码中特殊注释 TODO: + 说明:标识处有功能代码待编写,待实现的功能在说明中会简略说明. FIXME: + 说明:标识处代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说 ...

  7. 51Nod 1183 编辑距离 (字符串相似算法)

    编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除 ...

  8. BZOJ1040: [ZJOI2008]骑士 树套环DP

    题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ...

  9. DVA知识集合

    react与dva 原文地址:https://github.com/dvajs/dva-knowledgemap 1.变量声明 const DELAY = 1000 let count = 0 cou ...

  10. SVN的使用01

    关于svn的使用以及TortoiseSVN常见操作 一.关于svn介绍 在介绍之前提一下,MyEclipse项目组的建立,以及源文件夹的创建. 新建的那一栏点击other 在搜索栏中搜索Java Wo ...