Windows Hooks with golang

huangapple go评论82阅读模式
英文:

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

huangapple
  • 本文由 发表于 2014年6月10日 05:44:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/24129575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定