c++/cli mixed codes for standard c++ and csharp

时间:2022-09-01 19:07:28

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

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


 

工程目录结构

c++/cli mixed codes for standard c++ and csharp

HidEvent.h
1 #pragma once
2 
3 typedef void (*HidEvent)();
4 typedef void (__cdecl *HidReadDataEvent)(unsigned char *data, int len);
Hidimpl.h
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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 };
View Code
Hidimpl.cpp
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
  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(0), 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, 0, 0);
 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, 0, 0, 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 = 0;
 76     while (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, &guid, device_interface_index, &device_interface_data))
 77     {
 78         DWORD requireSize;
 79         SetupDiGetDeviceInterfaceDetail(hdevinfo, &device_interface_data, NULL, 0, &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, 0, 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, 0, 
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 = {0};
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(0, wndClass.lpszClassName, NULL, 
188             0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
189         if (hwnd != INVALID_HANDLE_VALUE)
190         {
191             GUID guid;
192             HidD_GetHidGuid(&guid);
193             DEV_BROADCAST_DEVICEINTERFACE notifycationFilter = {0};
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, 0, 0) > 0)
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 0;
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 = 0; 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, 0, _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 }
View Code
HidState.h
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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 };
View Code
HidState.cpp
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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 > 0)
24         {
25             unsigned char *ptrdt = new unsigned char[count];
26             for (int i = 0; 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, 0, 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 }
View Code

_______export,wrap managed clr class for csharp

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 };
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, 0, 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接口
PInvoke(平台调用)
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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
View Code
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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 0;
24 }
25 
26 ZSHIDLIB_API int getInputLen()
27 {
28     if (pHidimpl != nullptr)
29         return pHidimpl->getInputLen();
30 
31     return 0;
32 }
33 
34 ZSHIDLIB_API int getOutputLen()
35 {
36     if (pHidimpl != nullptr)
37         return pHidimpl->getOutputLen();
38 
39     return 0;
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 }
View Code
  • C#中的使用
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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, 0, len);
30             
31             // Log
32             Console.WriteLine("// usr subscription //_____________________________________");
33             for (int i = 0; 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[65];
58                     // ab 69 42 01 fe aa 00 00 aa cd
59                     int i = 0;
60                     buffer[i++] = 0;
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 }
View Code
  • Standard C++中的使用
c++/cli mixed codes for standard c++ and csharpc++/cli mixed codes for standard c++ and csharp
 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 = 0; 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[65] = {0x00, 0xab, 0x69, 0x42, 0x01, 0xfe, 0xaa, 0x00, 0x00, 0xaa, 0xcd};
37         hidImpl->Write(buffer, 65);
38 
39         Sleep(5000);
40     }
41 
42     system("pause");
43 
44     return 0;
45 }
View Code

c++/cli mixed codes for standard c++ and csharp

  • 参考书籍/资料

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

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