我有 C DLL 库,我尝试向它添加 python 接口。这是头文件:
typedef struct
{
unsigned int keyIdx : 8; // index of the G key or mouse button, for example, 6 for G6 or Button 6
unsigned int keyDown : 1; // key up or down, 1 is down, 0 is up
unsigned int mState : 2; // mState (1, 2 or 3 for M1, M2 and M3)
unsigned int mouse : 1; // indicate if the Event comes from a mouse, 1 is yes, 0 is no.
unsigned int reserved1 : 4; // reserved1
unsigned int reserved2 : 16; // reserved2
} GkeyCode;
// Callback used to allow client to react to the Gkey events. It is called in the context of another thread.
typedef void (__cdecl *logiGkeyCB)(GkeyCode gkeyCode, const wchar_t* gkeyOrButtonString, void* context);
typedef struct
{
logiGkeyCB gkeyCallBack;
void* gkeyContext;
} logiGkeyCBContext;
// Enable the Gkey SDK by calling this function
BOOL LogiGkeyInit(logiGkeyCBContext* gkeyCBContext);
// Enable the Gkey SDK by calling this function if not using callback. Use this initialization if using Unreal Engine
BOOL LogiGkeyInitWithoutCallback();
//Enable the Gkey SDK be calling this function if not using context. Use this initialization if working with Unity Engine
BOOL LogiGkeyInitWithoutContext(logiGkeyCB gkeyCallBack);
// Check if a mouse button is currently pressed
BOOL LogiGkeyIsMouseButtonPressed(const int buttonNumber);
// Get friendly name for mouse button
wchar_t* LogiGkeyGetMouseButtonString(const int buttonNumber);
// Check if a keyboard G-key is currently pressed
BOOL LogiGkeyIsKeyboardGkeyPressed(const int gkeyNumber,const int modeNumber);
// Get friendly name for G-key
wchar_t* LogiGkeyGetKeyboardGkeyString(const int gkeyNumber,const int modeNumber);
// Disable the Gkey SDK, free up all the resources.
void LogiGkeyShutdown();
我尝试这样的事情:
import ctypes
import time
# Define the GkeyCode structure
class GkeyCode(ctypes.Structure):
_fields_ = [
("keyIdx", ctypes.c_uint, 8),
("keyDown", ctypes.c_uint, 1),
("mState", ctypes.c_uint, 2),
("mouse", ctypes.c_uint, 1),
("reserved1", ctypes.c_uint, 4),
("reserved2", ctypes.c_uint, 16)
]
# Define the logiGkeyCBContext structure
class logiGkeyCBContext(ctypes.Structure):
_fields_ = [
("gkeyCallBack", ctypes.CFUNCTYPE(None, GkeyCode, ctypes.c_wchar_p, ctypes.c_void_p)),
("gkeyContext", ctypes.c_void_p)
]
# Load the Logitech Gaming G-key SDK dynamic library
dll_path = "C:\\Program Files\\Logitech Gaming Software\\GkeySDK_8.57.148\\Lib\\GameEnginesWrapper\\x64\\LogitechGkeyEnginesWrapper.dll"
gkey_lib = ctypes.CDLL(dll_path)
# Define the callback function
def gkey_callback(gkeyCode, gkeyOrButtonString, context):
print(f"Received G-key or button event: keyIdx={gkeyCode.keyIdx}, keyDown={gkeyCode.keyDown}, mState={gkeyCode.mState}, mouse={gkeyCode.mouse}")
print(f"G-key or button string: {gkeyOrButtonString}")
print(f"Context: {context}")
# Create an instance of the logiGkeyCBContext structure
context = logiGkeyCBContext()
callback_func_type = ctypes.CFUNCTYPE(None, GkeyCode, ctypes.c_wchar_p, ctypes.c_void_p)
callback_func = callback_func_type(gkey_callback)
context.gkeyCallBack = callback_func
context.gkeyContext = ctypes.c_void_p(0) # Set the context to whatever is appropriate
# Call the Logitech Gaming G-key SDK function that accepts the logiGkeyCBContext structure
gkey_lib.LogiGkeyInit.restype = ctypes.c_bool
gkey_lib.LogiGkeyInit.argtypes = (ctypes.POINTER(logiGkeyCBContext),)
success = gkey_lib.LogiGkeyInit(ctypes.byref(context))
if success:
print("Logitech Gaming G-key SDK initialized successfully.")
else:
print("Failed to initialize Logitech Gaming G-key SDK.")
c = 0
while c < 100:
c += 1
time.sleep(0.1)
# When done, shutdown the G-key SDK
gkey_lib.LogiGkeyShutdown()
运行,初始化成功,但随后我尝试按下任何 G 键,但从未执行回调? 以上是我的代码。
LogitechGkeyEnginesWrapper.dll
库是罗技 G-Key SDK 的一部分,可在此处获取参考:https://www.logitechg.com/sdk/GkeySDK_8.57.148.zip
SDK中有C++的例子
// DisplayGkeysDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DisplayGkeys.h"
#include "DisplayGkeysDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define CALLBACKMSG (WM_USER + 1)
HWND g_hwnd = NULL;
//Comment this to enable the polling method and disable the callback
#define USE_CALLBACK
#include "LogitechGkeyLib.h"
#pragma comment(lib, "LogitechGkeyLib.lib")
void __cdecl GkeySDKCallback(GkeyCode gkeyCode, wchar_t* gkeyOrButtonString, void* /*pContext*/)
{
SendMessage(g_hwnd, CALLBACKMSG, (WPARAM)&gkeyCode, (LPARAM)gkeyOrButtonString);
}
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CDisplayGkeysDlg dialog
CDisplayGkeysDlg::CDisplayGkeysDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CDisplayGkeysDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDisplayGkeysDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_GKEYS, m_listGkeys);
}
BEGIN_MESSAGE_MAP(CDisplayGkeysDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_CLOSE()
END_MESSAGE_MAP()
// CDisplayGkeysDlg message handlers
BOOL CDisplayGkeysDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
g_hwnd = m_hWnd;
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
SetTimer(1, 30,NULL);
logiGkeyCBContext gkeyContext;
ZeroMemory(&gkeyContext, sizeof(gkeyContext));
gkeyContext.gkeyCallBack = (logiGkeyCB)GkeySDKCallback;
gkeyContext.gkeyContext = NULL;
#ifdef USE_CALLBACK
LogiGkeyInit(&gkeyContext);
#else
LogiGkeyInit(NULL);
#endif // USE_CALLBACK
return TRUE; // return TRUE unless you set the focus to a control
}
void CDisplayGkeysDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDisplayGkeysDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDisplayGkeysDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CDisplayGkeysDlg::OnTimer(UINT_PTR nIDEvent)
{
for (int index = 6; index <= LOGITECH_MAX_MOUSE_BUTTONS; index++)
{
if (LogiGkeyIsMouseButtonPressed(index))
{
m_listGkeys.InsertString(m_listGkeys.GetCount(), LogiGkeyGetMouseButtonString(index));
m_listGkeys.SetCaretIndex(m_listGkeys.GetCount() - 1);
}
}
for (int index = 1; index <= LOGITECH_MAX_GKEYS; index++)
{
for (int mKeyIndex = 1; mKeyIndex <= LOGITECH_MAX_M_STATES; mKeyIndex++)
{
if (LogiGkeyIsKeyboardGkeyPressed(index, mKeyIndex))
{
m_listGkeys.InsertString(m_listGkeys.GetCount(), LogiGkeyGetKeyboardGkeyString(index, mKeyIndex));
m_listGkeys.SetCaretIndex(m_listGkeys.GetCount() - 1);
}
}
}
CDialogEx::OnTimer(nIDEvent);
}
void CDisplayGkeysDlg::OnClose()
{
LogiGkeyShutdown();
CDialogEx::OnClose();
}
BOOL CDisplayGkeysDlg::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
if (message == CALLBACKMSG)
{
GkeyCode* gkeyCode = (GkeyCode*)wParam;
//wchar_t* text = (wchar_t*)lParam; // Can use text from callback, or use SDK function
wchar_t* text = NULL;
if (gkeyCode->mouse)
{
text = LogiGkeyGetMouseButtonString(gkeyCode->keyIdx);
lstrcatW(text, (1 == gkeyCode->keyDown) ? L" down" : L" up");
m_listGkeys.InsertString(m_listGkeys.GetCount(), text);
m_listGkeys.SetCaretIndex(m_listGkeys.GetCount() - 1);
}
else
{
text = LogiGkeyGetKeyboardGkeyString(gkeyCode->keyIdx, gkeyCode->mState);
lstrcatW(text, (1 == gkeyCode->keyDown) ? L" down" : L" up");
m_listGkeys.InsertString(m_listGkeys.GetCount(), text);
m_listGkeys.SetCaretIndex(m_listGkeys.GetCount() - 1);
}
}
return CDialogEx::OnWndMsg(message, wParam, lParam, pResult);
}
任何人都知道哪里出了问题,或将我推向正确的方向?