我有以下代码,可以正常工作。
import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;
void*[] hWndList;
extern (Windows) int callback(void* hWnd, long /* lParams */ ) nothrow {
hWndList ~= hWnd;
return true;
}
void main() {
EnumWindows(&callback, 0);
writeln(hWndList);
}
我希望可以使用类似于JavaScript语法的内容:(void* hWnd, long) => {}
。
我尝试了此操作,但签名出现错误,它表示该函数是委托,并且Windows API显然不能接受委托。
import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;
void main() {
void*[] hWndList;
EnumWindows((void* hWnd, long /* lParams */ ) nothrow {
hWndList ~= hWnd; return true;
}, 0);
writeln(hWndList);
}
我什至不会粘贴编译器错误,因为我非常清楚地以错误的方式进行处理。
当然,将每个回调定义为单独的函数没有错,但是随之而来的是命名它们的问题。我也不喜欢它使我的代码看起来像这样。
谢谢。
答案 0 :(得分:1)
我发现我可以将委托(或lambda)转换为MSDN文档为EnumWindowsProc
指定的正确签名。
我也没有意识到,通过从全局范围隐式使用hWndList
来访问D程序的框架是一种非常糟糕的做法。
这就是我用来创建正确签名的方法。
alias EnumWindowsProc = extern (Windows) int function(HWND, LPARAM) nothrow;
然后我发现别名在{2}行的ENUMWINDOWSPROC
的MinGW标头中已经以core.sys.windows.windows
的形式存在(在撰写本文时)。
extern (Windows) nothrow {
...
alias BOOL function(HWND, LPARAM) ENUMWINDOWSPROC;
...
}
为解决隐式传递D帧的问题,我在EnumWindows
中将cast(LPARAM) &hWndList
用作lParam
。
这成为现在使用指针的问题。我知道这可能很糟糕,欢迎提出任何建议,但我将其强制转换为指针。
*(cast(HWND[]*) lParam)
完整的代码如下所示。显然,这只是开始的一个最小示例,因此您可能需要将强制转换的指针分配给某些对象,这样在使用lParams
中的变量时就不会造成混淆。
import core.sys.windows.windows: EnumWindows, ENUMWINDOWSPROC;
import std.stdio: writeln;
void main() {
HWND[] hWndList;
EnumWindows(cast(ENUMWINDOWSPROC) (HWND hWnd, LPARAM lParam) {
*(cast(HWND[]*) lParam) ~= hWnd;
return true;
}, cast(LPARAM) &hWndList);
writeln(hWndList);
}
我希望这对某人有帮助,因为这让我感到困惑(仍然不确定我是否了解指针逻辑)。
感谢D论坛上的Boris-Barboris给我一些帮助。
https://forum.dlang.org/post/xxklxaajptppockvazeo@forum.dlang.org