diff --git a/Native/_CUESDK.cs b/Native/_CUESDK.cs
index 87c6bf8..7271717 100644
--- a/Native/_CUESDK.cs
+++ b/Native/_CUESDK.cs
@@ -10,6 +10,8 @@ namespace CUE.NET.Native
{
#region Libary Management
+ private static IntPtr _dllHandle = IntPtr.Zero;
+
///
/// Gets the loaded architecture (x64/x86).
///
@@ -17,72 +19,166 @@ namespace CUE.NET.Native
static _CUESDK()
{
+ LoadCUESDK();
+ }
+
+ ///
+ /// Reloads the SDK.
+ ///
+ internal static void Reload()
+ {
+ UnloadCUESDK();
+ LoadCUESDK();
+ }
+
+ private static void LoadCUESDK()
+ {
+ if (_dllHandle != IntPtr.Zero) return;
+
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
- LoadLibrary((LoadedArchitecture = Environment.Is64BitProcess ? "x64" : "x86") + "/CUESDK_2013.dll");
+ _dllHandle = LoadLibrary((LoadedArchitecture = Environment.Is64BitProcess ? "x64" : "x86") + "/CUESDK_2013.dll");
+
+ _corsairSetLedsColorsPointer = (CorsairSetLedsColorsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColors"), typeof(CorsairSetLedsColorsPointer));
+ _corsairGetDeviceCountPointer = (CorsairGetDeviceCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceCount"), typeof(CorsairGetDeviceCountPointer));
+ _corsairGetDeviceInfoPointer = (CorsairGetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceInfo"), typeof(CorsairGetDeviceInfoPointer));
+ _corsairGetLedPositionsPointer = (CorsairGetLedPositionsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedPositions"), typeof(CorsairGetLedPositionsPointer));
+ _corsairGetLedIdForKeyNamePointer = (CorsairGetLedIdForKeyNamePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedIdForKeyName"), typeof(CorsairGetLedIdForKeyNamePointer));
+ _corsairRequestControlPointer = (CorsairRequestControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairRequestControl"), typeof(CorsairRequestControlPointer));
+ _corsairPerformProtocolHandshakePointer = (CorsairPerformProtocolHandshakePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairPerformProtocolHandshake"), typeof(CorsairPerformProtocolHandshakePointer));
+ _corsairGetLastErrorPointer = (CorsairGetLastErrorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLastError"), typeof(CorsairGetLastErrorPointer));
+ }
+
+ private static void UnloadCUESDK()
+ {
+ if (_dllHandle == IntPtr.Zero) return;
+
+ // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free
+ while (FreeLibrary(_dllHandle)) ;
+ _dllHandle = IntPtr.Zero;
}
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
+ [DllImport("kernel32.dll")]
+ private static extern bool FreeLibrary(IntPtr dllHandle);
+
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name);
+
#endregion
- #region SDK-IMPORTS
+ #region SDK-METHODS
+
+ #region Pointers
+
+ private static CorsairSetLedsColorsPointer _corsairSetLedsColorsPointer;
+ private static CorsairGetDeviceCountPointer _corsairGetDeviceCountPointer;
+ private static CorsairGetDeviceInfoPointer _corsairGetDeviceInfoPointer;
+ private static CorsairGetLedPositionsPointer _corsairGetLedPositionsPointer;
+ private static CorsairGetLedIdForKeyNamePointer _corsairGetLedIdForKeyNamePointer;
+ private static CorsairRequestControlPointer _corsairRequestControlPointer;
+ private static CorsairPerformProtocolHandshakePointer _corsairPerformProtocolHandshakePointer;
+ private static CorsairGetLastErrorPointer _corsairGetLastErrorPointer;
+
+ #endregion
+
+ #region Delegates
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate bool CorsairSetLedsColorsPointer(int size, IntPtr ledsColors);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate int CorsairGetDeviceCountPointer();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate IntPtr CorsairGetDeviceInfoPointer(int deviceIndex);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate IntPtr CorsairGetLedPositionsPointer();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate CorsairKeyboardKeyId CorsairGetLedIdForKeyNamePointer(char keyName);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate bool CorsairRequestControlPointer(CorsairAccessMode accessMode);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate _CorsairProtocolDetails CorsairPerformProtocolHandshakePointer();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate CorsairError CorsairGetLastErrorPointer();
+
+ #endregion
+
+ // ReSharper disable EventExceptionNotDocumented
///
/// CUE-SDK: set specified leds to some colors. The color is retained until changed by successive calls. This function does not take logical layout into account
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern bool CorsairSetLedsColors(int size, IntPtr ledsColors);
-
- //#if WIN64
- // [DllImport("CUESDK.x64_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- //#else
- // [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- //#endif
- //internal static extern bool CorsairSetLedsColorsAsync(int size, CorsairLedColor* ledsColors, void(*CallbackType)(void*, bool, CorsairError), void* context);
+ internal static bool CorsairSetLedsColors(int size, IntPtr ledsColors)
+ {
+ return _corsairSetLedsColorsPointer(size, ledsColors);
+ }
///
/// CUE-SDK: returns number of connected Corsair devices that support lighting control.
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern int CorsairGetDeviceCount();
+ internal static int CorsairGetDeviceCount()
+ {
+ return _corsairGetDeviceCountPointer();
+ }
///
/// CUE-SDK: returns information about device at provided index
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr CorsairGetDeviceInfo(int deviceIndex);
+ internal static IntPtr CorsairGetDeviceInfo(int deviceIndex)
+ {
+ return _corsairGetDeviceInfoPointer(deviceIndex);
+ }
///
/// CUE-SDK: provides list of keyboard LEDs with their physical positions.
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr CorsairGetLedPositions();
+ internal static IntPtr CorsairGetLedPositions()
+ {
+ return _corsairGetLedPositionsPointer();
+ }
///
/// CUE-SDK: retrieves led id for key name taking logical layout into account.
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern CorsairKeyboardKeyId CorsairGetLedIdForKeyName(char keyName);
+ internal static CorsairKeyboardKeyId CorsairGetLedIdForKeyName(char keyName)
+ {
+ return _corsairGetLedIdForKeyNamePointer(keyName);
+ }
///
/// CUE-SDK: requestes control using specified access mode.
/// By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern bool CorsairRequestControl(CorsairAccessMode accessMode);
+ internal static bool CorsairRequestControl(CorsairAccessMode accessMode)
+ {
+ return _corsairRequestControlPointer(accessMode);
+ }
///
/// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern _CorsairProtocolDetails CorsairPerformProtocolHandshake();
+ internal static _CorsairProtocolDetails CorsairPerformProtocolHandshake()
+ {
+ return _corsairPerformProtocolHandshakePointer();
+ }
///
/// CUE-SDK: returns last error that occured while using any of Corsair* functions
///
- [DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern CorsairError CorsairGetLastError();
+ internal static CorsairError CorsairGetLastError()
+ {
+ return _corsairGetLastErrorPointer();
+ }
+
+ // ReSharper restore EventExceptionNotDocumented
#endregion
}