英文:
How to access a variable in an union in a struct from the Windows API?
问题
我得到了input.ki undefined (type C.INPUT has no field or method ki)
的错误。
我尝试使用union_
前缀,但没有成功。
有什么想法吗?
package main
// #include <windows.h>
// #include <winuser.h>
import "C"
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
// typedef struct tagINPUT {
// DWORD type;
// union {
// MOUSEINPUT mi;
// KEYBDINPUT ki;
// HARDWAREINPUT hi;
// };
// } INPUT, *PINPUT;
func main() {
var input C.INPUT
var keybdinput C.KEYBDINPUT
input._type = 1 // ok!
// input.ki = keybdinput // input.ki undefined (type C.INPUT has no field or method ki)
// input.union_ki = keybdinput // input.union_ki undefined (type C.INPUT has no field or method union_ki)
}
英文:
I got input.ki undefined (type C.INPUT has no field or method ki)
.
I tried using the 'union_' prefix but without any luck.
Any ideas?
<!-- language: lang-go -->
package main
// #include <windows.h>
// #include <winuser.h>
import "C"
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
// typedef struct tagINPUT {
// DWORD type;
// union {
// MOUSEINPUT mi;
// KEYBDINPUT ki;
// HARDWAREINPUT hi;
// };
// } INPUT, *PINPUT;
func main() {
var input C.INPUT
var keybdinput C.KEYBDINPUT
input._type = 1 // ok!
// input.ki = keybdinput // input.ki undefined (type C.INPUT has no field or method ki)
// input.union_ki = keybdinput // input.union_ki undefined (type C.INPUT has no field or method union_ki)
}
答案1
得分: 2
因为联合类型破坏了类型安全性,在Go语言中唯一访问它们的方式是使用unsafe包。我认为你可以这样做:
*(*C.KEYBDINPUT)(unsafe.Pointer(uintptr(unsafe.Pointer(&input)) + unsafe.Sizeof(C.DWORD))) = keybdinput
如果我需要经常处理这些类型,我会声明包装类型来简化操作:
type tagKbdInput struct {
typ uint32
ki C.KEYBDINPUT
}
type tagMouseInput struct {
typ uint32
mi C.MOUSEINPUT
}
type tagHardwareInput struct {
typ uint32
hi C.HARDWAREINPUT
}
然后,我可以使用更简单的转换方式通过unsafe.Pointer(无需指针算术)来访问它们:
(*tagKbdInput)(unsafe.Pointer(&input)).ki = keybdinput
英文:
Because unions break type safety, the only way to access them in Go is with the unsafe package. I think you could do it something like this:
*(*C.KEYBDINPUT)(unsafe.Pointer(uintptr(unsafe.Pointer(&input)) + unsafe.Sizeof(C.DWORD))) = keybdinput
If I needed to deal with these types much, I would declare wrapper types to make it easier:
type tagKbdInput struct {
typ uint32
ki C.KEYBDINPUT
}
type tagMouseInput struct {
typ uint32
mi C.MOUSEINPUT
}
type tagHardwareInput struct {
typ uint32
hi C.HARDWAREINPUT
}
Then I could use a simpler conversion through unsafe.Pointer (without pointer arithmetic) to access them:
(*tagKbdInput)(unsafe.Pointer(&input)).ki = keybdinput
答案2
得分: 0
我记得 Go 语言可能故意不支持以任何方式访问联合成员。我认为你需要编写一个 C 包装器访问函数来实现这个功能。
英文:
IIRC Go does not, probably intentionally, support access to union members in any way. I think you'll have to write a C wrapper accessor function(s) to do that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论