首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go类型转换和未导出的CGo类型

Go类型转换和未导出的CGo类型
EN

Stack Overflow用户
提问于 2012-11-23 20:35:25
回答 2查看 2.9K关注 0票数 2

假设有一个具有如下所定义的结构的CGo包:

代码语言:javascript
复制
package test
...
type Test struct {
    Field *C.C_Test
}
...

现在假设从其他地方得到unsafe.Pointer,我知道它指向C_Test C结构。

我是否正确地理解在包中而不是在test.Test中,完全没有办法从unsafe.Pointer值中创建新的test实例?

尝试使用像&test.Test{ptr}这样的东西(其中ptrunsafe.Pointer值),由于明显的原因,字段值中的message cannot use ptr (type unsafe.Pointer) as type *test._Ctype_C_Test失败了,而且类型转换到*test._Ctype_C_Test也不起作用,因为没有导出这种类型。

我认为让我的另一个模块使用CGo并在其中重新定义相同的C结构也是行不通的,因为这个包将有类似于client._Ctype_C_Test的东西,但是test.Test需要test._Ctype_C_Test,它们与打字机的观点不同。

一些背景:当我在库中使用GtkBuilder时,需要一种方法来创建这样的结构。

它的GtkBuilder.GetObject(name)方法返回*GObject指针,该指针又包含需要以某种方式转换成的unsafe.Pointer字段,比如gtk.GtkEntry结构。gtk.GtkEntry本身包含类型为gtk.GtkWidget的隐式字段,该字段具有显式的*C.GtkWidget类型,因此我需要将unsafe.Pointer转换为*C.GtkWidget,但我不能,正如我在上面的简单示例中所描述的那样。

更新:这里是我试图强制工作的代码:https://gist.github.com/4141343

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-29 19:42:23

我问了一个关于金坚果的问题,并给出了一个如何做我想做的事情的例子。现在看来起作用了。以下是Ian回答的代码:

代码语言:javascript
复制
var t test.Test
p := (*unsafe.Pointer)(unsafe.Pointer(&t.Field))
*p = unsafe.Pointer(u)

因此,所需要的是双重转换为unsafe.Pointer,然后转换为*unsafe.Pointer。我想出了以下代码来简化分配过程:

代码语言:javascript
复制
func Assign(to unsafe.Pointer, from unsafe.Pointer) {
    fptr := (*unsafe.Pointer)(from)
    tptr := (*unsafe.Pointer)(to)
    *tptr = *fptr
}

func Init(builder *gtk.GtkBuilder) {
    messageNameEntryWidget := gtk.GtkWidget{}
    Assign(unsafe.Pointer(&messageNameEntryWidget.Widget),
           unsafe.Pointer(&builder.GetObject("messageNameEntry").Object))
}

然后,我决定放弃使用GTK,因为这样做是痛苦的),但这与问题无关。

票数 3
EN

Stack Overflow用户

发布于 2012-11-23 21:05:11

就像

代码语言:javascript
复制
foo := test.Test{}
*(unsafe.Pointer)(&foo.Field) = ptr

也测试过了?我希望这能奏效。(希望如此。有点。)

编辑2012-11-24 13:42世界协调时:第二次尝试

代码语言:javascript
复制
package main

/*

#include <stdio.h>
#include <stdlib.h>

typedef struct {
        int foo;
        char *bar;
} Test_t;

void test_dump(Test_t *test) {
        printf(".foo %d, .bar %s\n", test->foo, test->bar);
}

void *test_new(int foo, char *bar) {
        Test_t *p = malloc(sizeof(Test_t));
        p->foo = foo;
        p->bar = bar;
        return p;
}

*/
import "C"

import "unsafe"

type Test struct {
        Field *C.Test_t
}

func main() {
        hello := C.CString("Hello")
        defer C.free(unsafe.Pointer(hello))
        test := &Test{(*C.Test_t)(C.test_new(42, hello))}
        C.test_dump(test.Field)
}
代码语言:javascript
复制
$ go clean && go build && ls
main.go  13535422
$ ./13535422 
.foo 42, .bar Hello
$ 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13535422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档