Implementing winapi(SendInput) with dart:ffi
Implementing winapi(SendInput) with dart:ffi
我正在尝试使用 ffi 在 dart 中实现 SendInput 函数。 它需要一个无符号整数、一个输入数组和一个整数。 我发现很难实现 INPUT 数组结构,这就是我到目前为止所做的:
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'user32.dart'; //import dylib
typedef SendInputC = Uint32 Function(
Uint32 cInputs, Pointer pInputs, Int32 cbSize);
typedef SendInputDart = int Function(int inputCount, Pointer inputs, int size);
int SendInput(int type, {MouseInput mi, KeyboardInput ki, HardwareInput hi}) {
final SendInputP =
dylib.lookupFunction<SendInputC, SendInputDart>('SendInput');
var input = Input.allocate(
type: type,
mi: mi?.addressOf ?? nullptr,
ki: ki?.addressOf ?? nullptr,
hi: hi?.addressOf ?? nullptr);
var result = SendInputP(1, input.addressOf, sizeOf<Input>());
return result;
}
class Input extends Struct {
@Uint32()
int type;
Pointer<MouseInput> mi;
Pointer<KeyboardInput> ki;
Pointer<HardwareInput> hi;
factory Input.allocate(
{int type,
Pointer<MouseInput> mi,
Pointer<KeyboardInput> ki,
Pointer<HardwareInput> hi}) =>
allocate<Input>().ref
..type = type
..mi = mi
..ki = ki
..hi = hi;
}
/// MouseInput struct
class MouseInput extends Struct {
@Int32()
int dx;
@Int32()
int dy;
@Uint32()
int mouseData;
@Uint32()
int dwFlags;
@Uint32()
int time;
@Uint32()
int dwExtraInfo;
factory MouseInput.allocate(
{int dx = 0,
int dy = 0,
int mouseData = 0,
int dwFlags = 0,
int time = 0,
int dwExtraInfo = 0}) =>
allocate<MouseInput>().ref
..dx = dx
..dy = dy
..mouseData = mouseData
..dwFlags = dwFlags
..time = time
..dwExtraInfo = dwExtraInfo;
}
class KeyboardInput extends Struct {
@Uint16()
int wVk;
@Uint16()
int wScan;
@Uint32()
int dwFlags;
@Uint32()
int time;
@Uint32()
int dwExtraInfo;
factory KeyboardInput.allocate(
{int wVk = 0,
int wScan = 0,
int dwFlags = 0,
int time = 0,
int dwExtraInfo = 0}) =>
allocate<KeyboardInput>().ref
..wVk = wVk
..wScan = wScan
..dwFlags = dwFlags
..time = time
..dwExtraInfo = dwExtraInfo;
}
class HardwareInput extends Struct {
@Uint32()
int uMsg;
@Uint16()
int wParamL;
@Uint16()
int wParamH;
factory HardwareInput.allocate(
{int uMsg = 0, int wParamL = 0, int wParamH = 0}) =>
allocate<HardwareInput>().ref
..uMsg = uMsg
..wParamL = wParamL
..wParamH = wParamH;
}
但是调用SendInput
函数不会产生任何效果并返回 0,例如,此代码不发送鼠标输入。
var mi = MouseInput.allocate(dx: 505, dy: 175, dwFlags: 0x0002);
var r = SendInput(0, mi: mi);
这就是函数在C++中的样子
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = 505;
input.mi.dy = 175;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.dwExtraInfo = 0;
input.mi.time = 0;
SendInput(1, &input, sizeof(input));
tagInput
结构包含联合,似乎它们尚未得到支持(https://github.com/dart-lang/sdk/issues/38491(,但我想知道在支持联合之前是否有解决方法。
你的方法行不通,因为你的结构太大了。您真正想要的是分配的内存具有与常规 C 版本相同的大小(即 28 字节(,因此如下所示:
class KeyboardInput extends Struct {
@Uint32() int type;
@Uint16() int virtualCode;
@Uint16() int scanCode;
@Uint32() int flags;
@Uint32() int time;
Pointer dwExtraInfo;
@Uint32() int _padding;
}
话虽如此 - 它仍然不起作用,我真的不知道为什么。我什至尝试只传递原始字节数组指针,这在 dart 中仍然不起作用(在 C 中它工作正常(。这可能是飞镖FFI本身的一个错误,但可能是很多其他的东西。我正在尝试破解它,因为我也需要它才能工作。
现在,您可以使用已弃用的函数:
import 'dart:ffi';
DynamicLibrary _user32 = DynamicLibrary.open("user32.dll");
typedef _keybd_event_C = Void Function(Uint8 bVk, Uint8 bScan, Uint32 dwFlags, Pointer dwExtraInfo);
typedef _keybd_event_Dart = void Function(int bVk, int bScan, int dwFlags, Pointer dwExtraInfo);
var keybd_event = _user32.lookupFunction<_keybd_event_C, _keybd_event_Dart>("keybd_event");
const MAPVK_VK_TO_VSC = 0;
typedef _MapVirtualKeyW_C = Uint32 Function(Uint32 uCode, Uint32 uMapType);
typedef _MapVirtualKeyW_Dart = int Function(int uCode, int uMapType);
var MapVirtualKeyW = _user32.lookupFunction<_MapVirtualKeyW_C, _MapVirtualKeyW_Dart>("MapVirtualKeyW");
void main() {
keybd_event(
0x5a,
MapVirtualKeyW(0x5a, MAPVK_VK_TO_VSC),
0,
nullptr);
}
附注: 此外,如果您需要WinAPI的更多函数,则可以使用我快速拼接在一起的飞镖绑定生成器来获取WinAPI函数。您只需运行它并将 WinAPI 函数粘贴到上方的文本区域中,底部区域应显示飞镖绑定。有时它缺少一些类型定义(只需添加另一个类型Mapping
(,但在大多数情况下,它:)工作得很好(不适用于结构坚韧(
相关文章:
- 如何使用 dart:ffi 将 Uint8List 转换为 C 等效数据类型
- 飞镖:FFI 的无效功能
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 如何从 node-ffi 调用 c++ 中以结构向量作为参数的方法?
- Implementing winapi(SendInput) with dart:ffi
- getch() 像 dart 中的函数
- 将数组从c++返回到rust FFI中的rust
- 如何通过 Rust FFI 调用C++构造函数?
- 来自 Pharo Smalltalk 的 ffi 呼叫上的分段错误
- 来自C 线程的节点FFI回调
- 为什么要以相反的顺序执行RUST功能和FFI C 功能
- Haskell FFI 导出的常量注释
- 如何通过C FFI从Prolog中获取C 变量
- C /LUA FFI将用户数据作为表格
- 如何从 dart 对用 C/C++ 编写的函数进行异步调用
- Node-ffi 绑定到 NULL 终止的 C 字符串数组,但得到“分段错误:11”
- 为什么 Dart 中的原生包装函数与非常轻量级的函数相比"DEFINE NATIVE ENTRY"如此重量级?
- 如何在DART中输入此C 代码
- 在C和我的语言之间创建FFI
- 如何将 FFI 数组作为 c_void 指针传递到代数的 DMatrix2?