d如此包装句柄
struct SafeHandle
{
Unique!void _safe;//.1
alias _safe this;
this( HANDLE h )
{
this._safe = h;
}
~this()
{
if ( cast(HANDLE)_safe !is null )
if ( cast(HANDLE)_safe != INVALID_HANDLE_VALUE )
{
if ( CloseHandle( cast(HANDLE)_safe ) == 0 )
cast(HANDLE)_safe = null;
}
}
ref HANDLE get()
{
return cast( HANDLE )_safe;
}
}
//使用:
SafeHandle open_keyboard_device2( LPCWSTR path, int* error_number )
{
...
SafeHandle dev_handle =
CreateFileW(
path,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( dev_handle.get() != INVALID_HANDLE_VALUE )
...
...
}
void processDevice( ... )
{
auto dev_handle = open_keyboard_device2( path, &err );
set_keyboard_indicator2( dev_handle, KEYBOARD_CAPS_LOCK_ON );
...
}
如何定义HANDLE
变量?从过程
返回什么?如何调用?
变量析构时关闭句柄(h)
?
明显方法是RAII
类型,其中析构器调用CloseHandle
.1
,你让Unique
成为SafeHandle
的成员.我从来没有用过Unique
,它有一个bug
(或设计问题?):其析构
函数如下:
~this()
{
if (_p !is null)
{
destroy(_p);
_p = null;
}
}
因为_p
是指针,destroy(_p)
不会解引用并析构它所指向的内容.这是Unique
的一个bug
.它应该:
destroy(*_p);
如下包装句柄
:
import std;
// 可编译:
alias HANDLE = void*;
alias LPCWSTR = string;
enum INVALID_HANDLE_VALUE = null;
enum FILE_SHARE_READ = 1;
enum FILE_SHARE_WRITE = 2;
enum NULL = null;
enum OPEN_EXISTING = 1000;
// 模拟系统函数
HANDLE CreateFileW(LPCWSTR path, int, int, void*, int, int, void*) {
auto handle = cast(HANDLE)(new int(42));
writeln("Created ", handle);
return handle;
}
int CloseHandle(HANDLE handle) {
writeln("Closing ", handle);
return 0;
}
// RAII句柄
struct Handle {
HANDLE value;
// 禁止复制和赋值
@disable this(this);
@disable typeof(this) opAssign(const(typeof(this)));
this(HANDLE value) {
this.value = value;
writeln("构造:", value);
}
~this() {
const ret = CloseHandle(value);
if (ret) {
stderr.writefln!"关闭%s失败"(value);
}
}
}
Handle open_keyboard_device2( LPCWSTR path, int* error_number )
{
// ...
HANDLE dev_handle =
CreateFileW(
path,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
// 要动态创建
// 指定了唯一的所有者:
auto result = Handle(dev_handle);
writeln("退出open_keyboard_device2");
return result;
// if ( dev_handle.get() != INVALID_HANDLE_VALUE ) {
// // ...
// }
// ...
}
void processDevice( ... )
{
int err;
auto dev_handle = open_keyboard_device2("foo", &err );
// set_keyboard_indicator2( dev_handle, KEYBOARD_CAPS_LOCK_ON );
// ...
writeln("退出processDevice");
}
void main() {
processDevice();
writeln("退出主");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现