使用Go封装FUSE

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

Wrapping FUSE from Go

问题

我正在尝试使用Go来封装FUSE。然而,我在处理struct fuse_operations时遇到了困难。我似乎无法通过声明type Operations C.struct_fuse_operations来公开operations结构体,因为成员是小写的,而且我的纯Go源代码必须使用C-hackery来设置成员。在这种情况下,我的第一个错误是“无法设置getattr”,这看起来是Go中默认复制构造函数的等效物。我的下一个尝试是公开一个接口,该接口期望GetAttrReadLink等,并生成C.struct_fuse_operations,并将函数指针绑定到调用给定接口的闭包。

这是我的代码(代码后面有解释):

  1. package fuse
  2. // #include <fuse.h>
  3. // #include <stdlib.h>
  4. import "C"
  5. import (
  6. "os"
  7. "unsafe"
  8. )
  9. type Operations interface {
  10. GetAttr(string, *os.FileInfo) int
  11. }
  12. func Main(args []string, ops Operations) int {
  13. argv := make([]*C.char, len(args) + 1)
  14. for i, s := range args {
  15. p := C.CString(s)
  16. defer C.free(unsafe.Pointer(p))
  17. argv[i] = p
  18. }
  19. cop := new(C.struct_fuse_operations)
  20. cop.getattr = func(*C.char, *C.struct_stat) int {}
  21. argc := C.int(len(args))
  22. return int(C.fuse_main_real(argc, &argv[0], cop, C.size_t(unsafe.Sizeof(cop)), nil))
  23. }
  1. package main
  2. import (
  3. "fmt"
  4. "fuse"
  5. "os"
  6. )
  7. type CpfsOps struct {
  8. a int
  9. }
  10. func (me *CpfsOps) GetAttr(string, *os.FileInfo) int {
  11. return -1;
  12. }
  13. func main() {
  14. fmt.Println(os.Args)
  15. ops := &CpfsOps{}
  16. fmt.Println("fuse main returned", fuse.Main(os.Args, ops))
  17. }

这会产生以下错误:
fuse.go:21[fuse.cgo1.go:23]: cannot use func literal (type func(*_Ctype_char, *_Ctype_struct_stat) int) as type *[0]uint8 in assignment

我不确定应该传递什么给C.struct_fuse_operations的这些成员,我在几个地方看到提到从C代码调用回Go代码是不可能的。

如果可能的话,我该怎么做?我如何为接口函数提供“默认”值,使其表现得好像对应的C.struct_fuse_operations成员设置为NULL?

英文:

I'm playing around with wrapping FUSE with Go. However I've come stuck with how to deal with struct fuse_operations. I can't seem to expose the operations struct by declaring type Operations C.struct_fuse_operations as the members are lower case, and my pure-Go sources would have to use C-hackery to set the members anyway. My first error in this case is "can't set getattr" in what looks to be the Go equivalent of a default copy constructor. My next attempt is to expose an interface that expects GetAttr, ReadLink etc, and then generate C.struct_fuse_operations and bind the function pointers to closures that call the given interface.

This is what I've got (explanation continues after code):

  1. package fuse
  2. // #include &lt;fuse.h&gt;
  3. // #include &lt;stdlib.h&gt;
  4. import &quot;C&quot;
  5. import (
  6. //&quot;fmt&quot;
  7. &quot;os&quot;
  8. &quot;unsafe&quot;
  9. )
  10. type Operations interface {
  11. GetAttr(string, *os.FileInfo) int
  12. }
  13. func Main(args []string, ops Operations) int {
  14. argv := make([]*C.char, len(args) + 1)
  15. for i, s := range args {
  16. p := C.CString(s)
  17. defer C.free(unsafe.Pointer(p))
  18. argv[i] = p
  19. }
  20. cop := new(C.struct_fuse_operations)
  21. cop.getattr = func(*C.char, *C.struct_stat) int {}
  22. argc := C.int(len(args))
  23. return int(C.fuse_main_real(argc, &amp;argv[0], cop, C.size_t(unsafe.Sizeof(cop)), nil))
  24. }
  25. package main
  26. import (
  27. &quot;fmt&quot;
  28. &quot;fuse&quot;
  29. &quot;os&quot;
  30. )
  31. type CpfsOps struct {
  32. a int
  33. }
  34. func (me *CpfsOps) GetAttr(string, *os.FileInfo) int {
  35. return -1;
  36. }
  37. func main() {
  38. fmt.Println(os.Args)
  39. ops := &amp;CpfsOps{}
  40. fmt.Println(&quot;fuse main returned&quot;, fuse.Main(os.Args, ops))
  41. }

This gives the following error:
<pre>fuse.go:21[fuse.cgo1.go:23]: cannot use func literal (type func(*_Ctype_char, *_Ctype_struct_stat) int) as type *[0]uint8 in assignment</pre>
I'm not sure what to pass to these members of C.struct_fuse_operations, and I've seen mention in a few places it's not possible to call from C back into Go code.

If it is possible, what should I do? How can I provide the "default" values for interface functions that acts as though the corresponding C.struct_fuse_operations member is set to NULL?

答案1

得分: 1

http://cheesesun.blogspot.com/2010/04/callbacks-in-cgo.html描述了一种通用的技术,尽管有些复杂。http://groups.google.com/group/golang-nuts/browse_thread/thread/abd0e30dafdbf297?tvc=2&pli=1描述了这个问题。

我怀疑如果你想处理函数指针而不是uintptrs,你将不得不对cgo进行修改。

英文:

http://cheesesun.blogspot.com/2010/04/callbacks-in-cgo.html describes a general - if somewhat convoluted - technique. http://groups.google.com/group/golang-nuts/browse_thread/thread/abd0e30dafdbf297?tvc=2&amp;pli=1 describes the problem.

I suspect that if you want to handle the function pointers as anything other than uintptrs, you'll have to hack on cgo.

huangapple
  • 本文由 发表于 2010年11月29日 16:25:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/4301964.html
匿名

发表评论

匿名网友

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

确定