如何使用不同包中的相同C类型?

如何使用不同包中的相同C类型?

问题描述:

I'm trying to use cairo bindings (Go package), which defines a wrapper structure with a C type in it, with a C function, but can't make it work.

The cairo package defines a Context:

package cairo
...
type Context struct {
    Ptr *C.cairo_t
}
...

Then, from the main package, I want to use its pointer:

package main
...
cr := cairo.Create(surf.Surface)
layout := C.pango_cairo_create_layout(cr.Ptr)
...

The C.pango_cairo_create_layout accepts *C.cairo_t, which is what cr.Ptr should be. However, the go compiler doesn't agree:

./main.go:114:157: cannot use cr.Ptr (type *cairo._Ctype_struct__cairo) as type *_Ctype_struct__cairo in argument to func literal

As can be seen, cr.Ptr is of type *cairo.C.cairo_t and not *C.cairo_t, that is, the package namespace is a part of the type.

I've found https://github.com/golang/go/issues/13467, which talks about a workaround using the combination of the reflect package and unsafe.Pointer. However, I can't make it work.

How do I correctly "bend" this so it compiles and works?

我正在尝试使用cairo绑定(Go包),该绑定定义了其中包含C类型的包装器结构 ,带有C函数,但无法正常工作。 p>

cairo包定义了一个上下文: p>

 包cairo 
  ... 
type上下文结构{
 Ptr * C.cairo_t 
} 
 ... 
  code>  pre> 
 
 

然后,从主程序包中,我想 使用其指针: p>

 包main 
 ... 
cr:= cairo.Create(surf.Surface)
layout:= C.pango_cairo_create_layout(cr.Ptr)\  n ... 
  code>  pre> 
 
 

C.pango_cairo_create_layout code>接受 * C.cairo_t code>,即 > cr.Ptr code>应该是。 但是,go编译器不同意: p>

  ./ main.go:114:157:不能将cr.Ptr(* cairo._Ctype_struct__cairo类型)用作* _Ctype_struct__cairo类型 在func文字的参数中
  code>  pre> 
 
 

可以看到, cr.Ptr code>的类型为 * cairo.C.cairo_t 而不是 * C.cairo_t code>,也就是说,程序包名称空间是该类型的一部分。 p>

我发现”> https://github.com/golang/go/issues/13467 ,其中讨论了使用 反射包和 unsafe.Pointer code>的组合。 但是,我无法使其正常工作。 p>

我该如何正确地“弯曲”该弯曲,以便其编译并 strong>起作用? p> DIV>

For those interested, I've figured it out.

package main
...
cr := cairo.Create(surf.Surface)
ptr := (*C.cairo_t)(unsafe.Pointer(reflect.ValueOf(cr.Ptr).Pointer()))
layout := C.pango_cairo_create_layout(ptr)
...

Maybe it can be done more simply, but this works.