英文:
Windows Hooks with golang
问题
我正在编写一个应用程序,将利用Win32 API的WH_KEYBOARD钩子,以便在没有焦点的情况下激活(即在前台显示)。回调函数自然是一个函数指针(类型为HOOKPROC)。关于WH_KEYBOARD和WH_KEYBOARD_LL的许多文档都说回调函数必须驻留在DLL中,而不能直接在EXE中,但我发现在Windows XP及以上版本中并非如此,所以我认为这是一个历史上的怪癖。
该应用程序是用Go语言编写的。我知道(并且已经为之做出了贡献)github.com/AllenDang/w32,但我没有看到可以用来处理函数指针的东西。由于goroutine的结构,这种操作是否可行?我知道从Go中调用C很简单,但对于这样的回调函数,该怎么处理函数指针呢?
目前,我使用的方法是编写一个通过标准输出发送消息的EXE,将其单独编译,使用go-bindata
将其包含进来,并在运行时将其写入临时文件并执行它,同时一个goroutine监视该进程的标准输出。这让我感到不舒服。请告诉我有没有更好的方法,而不使用外部进程和糟糕的IPC技巧。
英文:
I'm writing an application that will make use of the Win32 API WH_KEYBOARD hook so that it can be activated (i.e., displayed in the foreground) without having focus. The callback, naturally, is a function pointer (of type HOOKPROC). A lot of the documentation for WH_KEYBOARD and WH_KEYBOARD_LL says that the callback has to reside in a DLL and cannot directly be in an EXE, however I've found that not to be true in Windows XP and above so I think that's a historical quirk.
The application is written in Go. I'm aware of (and have contributed to) github.com/AllenDang/w32, but I don't see anything that can be used to deal with function pointers. Due to the structure of goroutines, is this even possible? I know that calling C from Go is simple, but what does one do about function pointers for callbacks like this?
Right now my kludge is to write an EXE that sends a message via the standard output, compile it separately, include it using go-bindata
and at runtime write this to a temporary file and execute it, while a goroutine watches that process's standard output. It makes me cringe. Please tell me there's a better way without using an external process and awful IPC hackery.
1: https://github.com/AllenDang/w32 "AllenDang/w32"
答案1
得分: 4
请阅读关于cgo的维基页面。
你需要在C中定义回调函数,然后从中调用你的Go函数:
首先导出你的Go回调函数:
//export gocb
func gocb() {
}
然后在hook.c
中定义你的回调函数:
#include "_cgo_export.h"
void c_callback() {
gocb();
}
这是一个(非常丑陋的)示例:https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.go#L129,https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.h和https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.c#L49
英文:
Read the wiki page about cgo.
You will have to define the callback in C and then call your Go function from it:
First export your Go callback :
//export gocb
func gocb() {
}
Then define your callback in say hook.c
#include "_cgo_export.h"
void c_callback() {
gocb();
}
It's my code and I hacked it up to test something, never had the time to clean it up after that.
Here's an (ugly ugly) example: https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.go#L129, https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.h and https://github.com/OneOfOne/go-nfqueue/blob/master/nfqueue.c#L49
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论