c++/cli mixed codes for standard c++ and csharp
混合DotNet与Win32API来实现的Hidlibrary,c/c++可直接使用,c#可直接使用
异步IO,拔插事件订阅,数据读取事件订阅
工程目录结构
- HidEvent.h
- #pragma once
- typedef void (*HidEvent)();
- typedef void (__cdecl *HidReadDataEvent)(unsigned char *data, int len);
- Hidimpl.h
- #pragma once
- #include "HidEvent.h"
- class Hidimpl
- {
- public:
- Hidimpl(int vid, int pid);
- ~Hidimpl(void);
- bool FindMyDevice();
- void NotifyEvents(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
- int getInputLen()
- {
- return mInputLen;
- }
- int getOutputLen()
- {
- return mOutputLen;
- }
- bool IsConnected()
- {
- return mIsConnected;
- }
- public:
- // IO Functions
- //int Read(unsigned char *data, int len);
- void Write(unsigned char *data, int len);
- public:
- static Hidimpl *mTarget;
- static DWORD ThreadMessageRoutine(LPVOID lparam);
- static LRESULT CALLBACK ZSHidWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
- public:
- HidEvent mArrivalEvent;
- HidEvent mRemovedEvent;
- HidReadDataEvent mReadDataEvent;
- private:
- void MyDeviceRemoved();
- private:
- int mInputLen;
- int mOutputLen;
- bool mIsConnected;
- int mVid;
- int mPid;
- HANDLE mhHidRx;
- HANDLE mhHidTx;
- DWORD mThreadId;
- HANDLE mThreadHandle;
- // Managed objects FileStream
- void *mFsRx;
- void *mFsTx;
- };
- Hidimpl.cpp
- #include "StdAfx.h"
- #include "Hidimpl.h"
- #include "HidState.h"
- #include <vcclr.h>
- #pragma comment(lib, "hid.lib")
- #pragma comment(lib, "setupapi.lib")
- using namespace System;
- using namespace System::IO;
- using namespace Microsoft::Win32::SafeHandles;
- Hidimpl *Hidimpl::mTarget = nullptr;
- Hidimpl::Hidimpl(int vid, int pid)
- :mFsRx(nullptr), mFsTx(nullptr),
- mArrivalEvent(nullptr), mRemovedEvent(nullptr),
- mThreadId(), mThreadHandle(INVALID_HANDLE_VALUE)
- {
- mVid = vid;
- mPid = pid;
- FindMyDevice();
- }
- Hidimpl::~Hidimpl(void)
- {
- MyDeviceRemoved();
- if (mThreadHandle != INVALID_HANDLE_VALUE)
- {
- PostThreadMessage(mThreadId, WM_CLOSE, , );
- mThreadHandle = INVALID_HANDLE_VALUE;
- }
- }
- void Hidimpl::MyDeviceRemoved()
- {
- if (mFsRx)
- {
- gcroot<FileStream ^> *_pfs = static_cast<gcroot<FileStream ^> *>(mFsRx);
- // not need only delete ok
- //((FileStream ^)*_pfs)->Close();
- delete _pfs;
- mFsRx = nullptr;
- }
- if (mFsTx)
- {
- gcroot<FileStream ^> *_pfs = static_cast<gcroot<FileStream ^> *>(mFsTx);
- // not need only delete ok
- //((FileStream ^)*_pfs)->Close();
- delete _pfs;
- mFsTx = nullptr;
- }
- // 不需要手动关闭GC自动处理
- // this is also a crazy fucking shit
- // 关闭的句柄被重复关闭会引发[0xC0000008: An invalid handle was specified]
- //CloseHandle(mhHidRx);
- //mhHidRx = INVALID_HANDLE_VALUE;
- //CloseHandle(mhHidTx);
- //mhHidTx = INVALID_HANDLE_VALUE;
- }
- bool Hidimpl::FindMyDevice()
- {
- bool isFind = false;
- GUID guid;
- HidD_GetHidGuid(&guid);
- HDEVINFO hdevinfo = SetupDiGetClassDevs(&guid, , , DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
- SP_DEVICE_INTERFACE_DATA device_interface_data;
- ZeroMemory(&device_interface_data, sizeof(device_interface_data));
- device_interface_data.cbSize = sizeof(device_interface_data);
- int device_interface_index = ;
- while (SetupDiEnumDeviceInterfaces(hdevinfo, NULL, &guid, device_interface_index, &device_interface_data))
- {
- DWORD requireSize;
- SetupDiGetDeviceInterfaceDetail(hdevinfo, &device_interface_data, NULL, , &requireSize, NULL);
- PSP_DEVICE_INTERFACE_DETAIL_DATA psp_device_interface_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requireSize);
- psp_device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
- if (SetupDiGetDeviceInterfaceDetail(hdevinfo, &device_interface_data, psp_device_interface_detail_data, requireSize, &requireSize, NULL))
- {
- TCHAR *device_path = psp_device_interface_detail_data->DevicePath;
- // 打印设备路径[将TCHAR *转换为System::String^]
- //String ^str_path = gcnew String(device_path);
- //Console::ForegroundColor = ConsoleColor::Blue;
- //Console::WriteLine(str_path);
- //Console::ResetColor();
- HANDLE handle = CreateFile(device_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
- if (handle != INVALID_HANDLE_VALUE)
- {
- HIDD_ATTRIBUTES hidd_attributes;
- HidD_GetAttributes(handle, &hidd_attributes);
- if (hidd_attributes.VendorID == mVid && hidd_attributes.ProductID == mPid)
- {
- PHIDP_PREPARSED_DATA phidp_preparsed_data;
- HidD_GetPreparsedData(handle, &phidp_preparsed_data);
- HIDP_CAPS hidp_caps;
- HidP_GetCaps(phidp_preparsed_data, &hidp_caps);
- mInputLen = hidp_caps.InputReportByteLength;
- mOutputLen = hidp_caps.OutputReportByteLength;
- HidD_FreePreparsedData(phidp_preparsed_data);
- // 打印设备路径[将TCHAR *转换为System::String^]
- String ^str_path = gcnew String(device_path);
- Console::ForegroundColor = ConsoleColor::Green;
- Console::WriteLine(str_path);
- Console::ResetColor();
- mhHidRx = CreateFile(device_path, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
- mhHidTx = CreateFile(device_path, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
- SafeFileHandle ^_hRx = gcnew SafeFileHandle((IntPtr)mhHidRx, true);
- FileStream ^_fsRx = gcnew FileStream(_hRx, FileAccess::Read, mInputLen, true);
- // managed type conversion into unmanaged pointer is not allowed.
- // we can use gcroot<> wrapper
- gcroot<FileStream^> *_pfs = new gcroot<FileStream ^>(_fsRx);
- mFsRx = static_cast<void *>(_pfs);
- SafeFileHandle ^_hTx = gcnew SafeFileHandle((IntPtr)mhHidTx, true);
- FileStream ^_fsTx = gcnew FileStream(_hTx, FileAccess::Write, mOutputLen, true);
- // managed type conversion into unmanaged pointer is not allowed.
- // we can use gcroot<> wrapper
- _pfs = new gcroot<FileStream^>(_fsTx);
- mFsTx = static_cast<void *>(_pfs);
- HidState ^state = gcnew HidState(this, _fsRx, mInputLen);
- _fsRx->BeginRead(state->mBuffer, , state->mBuffer->Length, gcnew AsyncCallback(state, &HidState::EndRead), state);
- isFind = true;
- CloseHandle(handle);
- free(psp_device_interface_detail_data);
- break;
- }
- CloseHandle(handle);
- }
- }
- else
- {
- int error = GetLastError();
- Console::ForegroundColor = ConsoleColor::Blue;
- Console::WriteLine("[SetupDiGetDeviceInterfaceDetail Error]GetLastError = " + error);
- Console::ResetColor();
- }
- device_interface_index++;
- free(psp_device_interface_detail_data);
- }
- SetupDiDestroyDeviceInfoList(hdevinfo);
- mIsConnected = isFind;
- return isFind;
- }
- void Hidimpl::NotifyEvents(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata)
- {
- // Cannt reset event to device
- if (mThreadHandle != INVALID_HANDLE_VALUE) return;
- mArrivalEvent = arrival;
- mRemovedEvent = removed;
- mReadDataEvent = rdata;
- mThreadHandle = CreateThread(NULL, ,
- (LPTHREAD_START_ROUTINE)ThreadMessageRoutine, this, THREAD_PRIORITY_NORMAL, &mThreadId);
- }
- DWORD Hidimpl::ThreadMessageRoutine(LPVOID lparam)
- {
- mTarget = static_cast<Hidimpl *>(lparam);
- HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(NULL));
- WNDCLASS wndClass = {};
- wndClass.lpfnWndProc = ZSHidWndProc;
- wndClass.lpszClassName = L"ZSHidlib";
- wndClass.hInstance = hInstance;
- if (RegisterClass(&wndClass))
- {
- // 为线程消息循环(HWND_MESSAGE)
- HWND hwnd = CreateWindowEx(, wndClass.lpszClassName, NULL,
- , , , , , HWND_MESSAGE, NULL, hInstance, NULL);
- if (hwnd != INVALID_HANDLE_VALUE)
- {
- GUID guid;
- HidD_GetHidGuid(&guid);
- DEV_BROADCAST_DEVICEINTERFACE notifycationFilter = {};
- notifycationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
- notifycationFilter.dbcc_classguid = guid;
- notifycationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
- HDEVNOTIFY hdevnotify = RegisterDeviceNotification(hwnd, ¬ifycationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
- if (hdevnotify != INVALID_HANDLE_VALUE)
- {
- Console::ForegroundColor = ConsoleColor::Blue;
- Console::WriteLine("Notify注册成功,即将进入消息循环.");
- Console::ResetColor();
- MSG msg;
- if (GetMessage(&msg, NULL, , ) > )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- Console::ForegroundColor = ConsoleColor::Blue;
- Console::WriteLine("退出消息循环........................");
- Console::ResetColor();
- UnregisterDeviceNotification(hdevnotify);
- DestroyWindow(hwnd);
- UnregisterClass(wndClass.lpszClassName, hInstance);
- }
- }
- return ;
- }
- LRESULT CALLBACK Hidimpl::ZSHidWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
- {
- if (msg == WM_DEVICECHANGE)
- {
- switch (wparam)
- {
- case DBT_DEVICEARRIVAL:
- {
- if (!mTarget->mIsConnected)
- {
- if (mTarget->FindMyDevice())
- {
- Console::ForegroundColor = ConsoleColor::Blue;
- Console::WriteLine("MY HID DEVICE IS FOUND AND OPEN.");
- Console::ResetColor();
- // My device arrival event
- if (mTarget->mArrivalEvent != nullptr)
- mTarget->mArrivalEvent();
- }
- }
- }
- break;
- case DBT_DEVICEREMOVECOMPLETE:
- {
- if (mTarget->mIsConnected)
- {
- if (!mTarget->FindMyDevice())
- {
- Console::ForegroundColor = ConsoleColor::Blue;
- Console::WriteLine("MY HID DEVICE REMOVED.");
- Console::ResetColor();
- // My device remove event
- mTarget->MyDeviceRemoved();
- if (mTarget->mRemovedEvent != nullptr)
- mTarget->mRemovedEvent();
- }
- }
- }
- break;
- default:
- break;
- }
- }
- return DefWindowProc(hwnd, msg, wparam, lparam);
- }
- void Hidimpl::Write(unsigned char *data, int len)
- {
- if (!mIsConnected) return;
- array<unsigned char> ^_data = gcnew array<unsigned char>(mOutputLen);
- try
- {
- int length = len>mOutputLen?mOutputLen:len;
- for (int i = ; i < length; i++) _data[i] = data[i];
- if (mFsTx != nullptr)
- {
- gcroot<FileStream^> *_pfs = static_cast<gcroot<FileStream^> *>(mFsTx);
- //((FileStream^)*_pfs)->Write(_data, 0, _data->Length);
- ((FileStream^)*_pfs)->BeginWrite(_data, , _data->Length, nullptr, nullptr);
- ((FileStream^)*_pfs)->Flush();
- }
- }
- catch(IOException ^e)
- {
- Console::WriteLine(e->Message);
- }
- catch(Exception ^e)
- {
- Console::WriteLine(e->Message);
- }
- }
- HidState.h
- #pragma once
- #include "Hidimpl.h"
- using namespace System;
- using namespace System::IO;
- public ref class HidState
- {
- public:
- HidState(Hidimpl *hid, FileStream ^fs, int bufferLen);
- ~HidState();
- void EndRead(IAsyncResult ^ar);
- public:
- Hidimpl *mHidimpl;
- FileStream ^mFileStream;
- array<unsigned char> ^mBuffer;
- };
- HidState.cpp
- #include "stdafx.h"
- #include "HidState.h"
- HidState::HidState(Hidimpl *hid, FileStream ^fs, int bufferLen)
- {
- mHidimpl = hid;
- mFileStream = fs;
- mBuffer = gcnew array<unsigned char>(bufferLen);
- }
- HidState::~HidState()
- {
- mHidimpl = nullptr;
- }
- void HidState::EndRead(IAsyncResult ^ar)
- {
- HidState ^state = dynamic_cast<HidState ^>(ar->AsyncState);
- try
- {
- int count = state->mFileStream->EndRead(ar);
- // [有数据读入的情况下]调用ReadData事件
- if (mHidimpl->mReadDataEvent != nullptr && count > )
- {
- unsigned char *ptrdt = new unsigned char[count];
- for (int i = ; i < count; i++) ptrdt[i] = mBuffer[i];
- // 此处封送到C#的IntPtr指针(this a crazy fucking)
- mHidimpl->mReadDataEvent(ptrdt, count);
- delete []ptrdt;
- }
- if (mHidimpl->IsConnected())
- state->mFileStream->BeginRead(state->mBuffer, , mBuffer->Length, gcnew AsyncCallback(this, &HidState::EndRead), state);
- }
- catch(IOException ^e)
- {
- Console::WriteLine(e->Message);
- }
- catch(Exception ^e)
- {
- Console::WriteLine(e->Message);
- }
- }
_______export,wrap managed clr class for csharp
- Hidlib.h
- #pragma once
- #include "Hidimpl.h"
- using namespace System;
- public ref class Hidlib
- {
- public:
- delegate void HidDelegate();
- delegate void HidReadDataDelegate(IntPtr data, int len);
- public:
- Hidlib(int vid, int pid);
- void NotifyEvents(HidDelegate ^arrival, HidDelegate ^removed, HidReadDataDelegate ^rdata);
- void Write(array<unsigned char> ^data);
- private:
- Hidimpl *impl;
- };
- Hidlib.cpp
- #include "stdafx.h"
- #include "Hidlib.h"
- #include <vcclr.h>
- using namespace System::IO;
- using namespace System::Runtime::InteropServices;
- Hidlib::Hidlib(int vid, int pid)
- {
- impl = new Hidimpl(vid, pid);
- }
- void Hidlib::NotifyEvents(HidDelegate ^arrival, HidDelegate ^removed, HidReadDataDelegate ^rdata)
- {
- IntPtr _arrival = Marshal::GetFunctionPointerForDelegate(arrival);
- IntPtr _removed = Marshal::GetFunctionPointerForDelegate(removed);
- IntPtr _rdata = Marshal::GetFunctionPointerForDelegate(rdata);
- impl->NotifyEvents((HidEvent)_arrival.ToPointer(), (HidEvent)_removed.ToPointer(), (HidReadDataEvent)_rdata.ToPointer());
- }
- void Hidlib::Write(array<unsigned char> ^data)
- {
- try
- {
- int length = data->Length>impl->getOutputLen()?impl->getOutputLen():data->Length;
- if (impl->mFsTx != nullptr)
- {
- gcroot<FileStream^> *_pfs = static_cast<gcroot<FileStream^> *>(impl->mFsTx);
- //((FileStream^)*_pfs)->Write(_data, 0, _data->Length);
- ((FileStream^)*_pfs)->BeginWrite(data, , length, nullptr, nullptr);
- ((FileStream^)*_pfs)->Flush();
- }
- }
- catch(IOException ^e)
- {
- Console::WriteLine(e->Message);
- }
- catch(Exception ^e)
- {
- Console::WriteLine(e->Message);
- }
- }
- 提供PInvoke接口
- PInvoke(平台调用)
- #pragma once
- #include <Hidimpl.h>
- #include "HidEvent.h"
- #ifdef ZSHIDLIB_EXPORTS
- #define ZSHIDLIB_API __declspec(dllexport)
- #else
- #define ZSHIDLIB_API __declspec(dllimport)
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- ZSHIDLIB_API void Open(int vid, int pid);
- ZSHIDLIB_API bool IsOpen();
- ZSHIDLIB_API bool IsConnected();
- ZSHIDLIB_API int getInputLen();
- ZSHIDLIB_API int getOutputLen();
- ZSHIDLIB_API void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
- ZSHIDLIB_API void Write(unsigned char *data, int len);
- ZSHIDLIB_API void Close();
- #ifdef __cplusplus
- };
- #endif
- #include "stdafx.h"
- #include "Hidlib.h"
- #include "Hidimpl.h"
- Hidimpl *pHidimpl = nullptr;
- ZSHIDLIB_API void Open(int vid, int pid)
- {
- if (pHidimpl == nullptr)
- pHidimpl = new Hidimpl(vid, pid);
- }
- ZSHIDLIB_API bool IsOpen()
- {
- return (pHidimpl != nullptr);
- }
- ZSHIDLIB_API bool IsConnected()
- {
- if (pHidimpl != nullptr)
- return pHidimpl->IsConnected();
- return ;
- }
- ZSHIDLIB_API int getInputLen()
- {
- if (pHidimpl != nullptr)
- return pHidimpl->getInputLen();
- return ;
- }
- ZSHIDLIB_API int getOutputLen()
- {
- if (pHidimpl != nullptr)
- return pHidimpl->getOutputLen();
- return ;
- }
- ZSHIDLIB_API void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata)
- {
- if (pHidimpl != nullptr)
- {
- pHidimpl->NotifyEvents(arrival, removed, rdata);
- }
- }
- ZSHIDLIB_API void Write(unsigned char *data, int len)
- {
- if (pHidimpl != nullptr)
- pHidimpl->Write(data, len);
- }
- ZSHIDLIB_API void Close()
- {
- if (pHidimpl != nullptr)
- {
- delete pHidimpl;
- pHidimpl = nullptr;
- }
- }
- C#中的使用
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Runtime.InteropServices;
- namespace ZSHidApp
- {
- delegate void HidEvent();
- delegate void HidReadDataEvent(IntPtr data, int len);
- class Program
- {
- //[DllImport("ZSHidlib.dll")]
- //public static extern void Open(int vid, int pid);
- //[DllImport("ZSHidlib.dll")]
- //public static extern void Notify(HidEvent arrival, HidEvent removed, HidReadDataEvent rdata);
- //[DllImport("ZSHidlib.dll")]
- //public static extern void Write(Byte[] data, int len);
- //[DllImport("ZSHidlib.dll")]
- //public static extern void GetData(ref Byte[] data, int len);
- static void ReadData(IntPtr data, int len)
- {
- Byte[] _data = new Byte[len];
- Marshal.Copy(data, _data, , len);
- // Log
- Console.WriteLine("// usr subscription //_____________________________________");
- for (int i = ; i < _data.Length; i++) Console.Write(string.Format("{0:x2} ", _data[i]));
- Console.WriteLine();
- }
- static void Main(string[] args)
- {
- //Open(0x0b6a, 0x5346);
- //Notify(() => Console.WriteLine("______________device arrival."),
- // () => Console.WriteLine("__________________device removed."),
- // ReadData);
- Hidlib hidlib = new Hidlib(0x0b6a, 0x5346);
- hidlib.NotifyEvents(() => Console.WriteLine("______________device arrival."),
- () => Console.WriteLine("__________________device removed."),
- ReadData);
- while (true)
- {
- ConsoleKeyInfo keyInfo = Console.ReadKey();
- if (keyInfo.Key == ConsoleKey.Q)
- {
- break;
- }
- else if (keyInfo.Key == ConsoleKey.W)
- {
- Byte[] buffer = new Byte[];
- // ab 69 42 01 fe aa 00 00 aa cd
- int i = ;
- buffer[i++] = ;
- buffer[i++] = 0xab;
- buffer[i++] = 0x69;
- buffer[i++] = 0x42;
- buffer[i++] = 0x01;
- buffer[i++] = 0xfe;
- buffer[i++] = 0xaa;
- buffer[i++] = 0x00;
- buffer[i++] = 0x00;
- buffer[i++] = 0xaa;
- buffer[i++] = 0xcd;
- hidlib.Write(buffer);
- }
- }
- }
- }
- }
- Standard C++中的使用
- // ZSHidWin32App.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include "../ZSHidlib/Hidlib.h"
- #include "../ZSHidlib/Hidimpl.h"
- #pragma comment(lib, "../Debug/ZSHidlib.lib")
- void Arrival()
- {
- printf("______________________device arrival.\n");
- }
- void Removed()
- {
- printf("______________________device removed.\n");
- }
- void ReadData(unsigned char *data, int len)
- {
- for (int i = ; i < len; i++)
- {
- printf("%.2x ", data[i]);
- }
- printf("___________________call in ReadData callback function.");
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- Hidimpl *hidImpl = new Hidimpl(0x0b6a, 0x5346);
- hidImpl->NotifyEvents(Arrival, Removed, ReadData);
- while(true)
- {
- unsigned char buffer[] = {0x00, 0xab, 0x69, 0x42, 0x01, 0xfe, 0xaa, 0x00, 0x00, 0xaa, 0xcd};
- hidImpl->Write(buffer, );
- Sleep();
- }
- system("pause");
- return ;
- }
- 参考书籍/资料
《Visual C++/CLI从入门到精通》
《NET互操作 P_Invoke,C++Interop和COM Interop》
c++/cli mixed codes for standard c++ and csharp的更多相关文章
- 关于aws cli命令的exit/return code分析
最近总是收到一个备份脚本的失败邮件,脚本是之前同事写的,没有加入任何有调试信息,及有用的日志 于是去分析 ,脚本中有一条 aws s3 sync $srclocal $dsts3 命令,然后根据这条 ...
- Go 语言相关的优秀框架,库及软件列表
If you see a package or project here that is no longer maintained or is not a good fit, please submi ...
- 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 ...
- $geoNear
怎么使用mongoose的geoNear 2014-11-26 15:05:20| 分类: mongodb | 标签:mongoose |举报|字号 订阅 下载LOFTER我的照片书 ...
- mongodb的地理位置索引
mongoDB支持二维空间索引,使用空间索引,mongoDB支持一种特殊查询,如某地图网站上可以查找离你最近的咖啡厅,银行等信息.这个使用mongoDB的空间索引结合特殊的查询方法很容易实现.前提条件 ...
- Transparency Tutorial with C# - Part 1
Download demo project - 4 Kb Download source - 6 Kb Download demo project - 5 Kb Download source - 6 ...
- Awesome Go
A curated list of awesome Go frameworks, libraries and software. Inspired by awesome-python. Contrib ...
- CFA一级知识点总结
更多来自: www.vipcoursea.com Ethics 部分 Objective of codes and standard:永远是为了maintain public trust in ...
- 从早期 Spring Boot 版本升级
如果你现在正在从早期的 Spring Boot 版本进行升级的话,请访问 “migration guide” on the project wiki 页面,这个页面提供了有关升级的详细指南.同时也请查 ...
随机推荐
- [USACO19OPEN]Valleys P
题意 洛谷 做法 用并查集维护区域,剩下的就只用判是否有洞就好了 然后手玩出一个结论:凸角为\(+1\),凹角为\(-1\),和为\(sum\),洞数\(h\),满足\(sum=4-4h\) 位置\( ...
- 【sklearn】Toy datasets上的分类/回归问题 (XGBoost实践)
分类问题 1. 手写数字识别问题 from sklearn.datasets import load_digits digits = load_digits() # 加载手写字符识别数据集 X = d ...
- Java出现次数最多的整数
描述 编写一个程序,读入一组整数,这组整数是按照从小到大的顺序排列的,它们的个数N也是由用户输入的,最多不会超过20.然后程序将对这个数组进行统计,把出现次数最多的那个数组元素值打印出来.如果有两个元 ...
- 【Spring】事务(transactional)之初步理解
一. 场景 有一个定时器,做数据库表数据同步. 把数据库A的表table(DB_A_TABLE)同步到数据库B的表table(DB_B_TABLE). 对于DB_A_TABLE的每行数据要做一定的逻辑 ...
- win10家庭版更改本地账户名、C盘Users下文件夹名和环境变量等
PS:由于四五年前装系统的时候懵懵懂懂的敲了一个中文用户名(有一个字还打错了,尴尬),导致现在打开cmd默认是C:\Users\中文名,path环境变量中也有中文路径,有时候有些程序的路径也是中文,这 ...
- Java代码中特殊注释
Java代码中特殊注释 TODO: + 说明:标识处有功能代码待编写,待实现的功能在说明中会简略说明. FIXME: + 说明:标识处代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说 ...
- 51Nod 1183 编辑距离 (字符串相似算法)
编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除 ...
- BZOJ1040: [ZJOI2008]骑士 树套环DP
题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ...
- DVA知识集合
react与dva 原文地址:https://github.com/dvajs/dva-knowledgemap 1.变量声明 const DELAY = 1000 let count = 0 cou ...
- SVN的使用01
关于svn的使用以及TortoiseSVN常见操作 一.关于svn介绍 在介绍之前提一下,MyEclipse项目组的建立,以及源文件夹的创建. 新建的那一栏点击other 在搜索栏中搜索Java Wo ...