如何从Go函数返回C指针?

时间:2017-10-05 17:41:47

标签: c go cgo gccgo

我有疑问是否可以从C上的Go函数指针返回?例如,main.c可以是:

struct open_db_return db_ptr = open_db(db_path);
  GoSlice backet = {"DB", 2, 2};
  GoSlice key = {"CONFIG", 6, 6};
  struct get_value_return val = get_value(db_ptr.r0, backet, key);
  close_db(db_ptr.r0);

接下来是代码:

//export open_db
func open_db(path string) (interface{}, error) {
    db, err := db.Open(path, 0600, nil)
    if err != nil {
        return nil, err
    }
    return db, nil
}

//export close_db
func close_db(db interface{}) {
    ldb := db.(*db.DB)
    ldb.Close()
}

//export get_value
func get_value(db interface{}, backet_name []byte, key_name []byte) ([]byte, error) {
    ldb := db.(*db.DB)
    var value []byte
    fn := func(tx *db.Tx) error {
        value = tx.Bucket(backet_name).Get(key_name)
        return nil
    }
    return value, ldb.View(fn)
}

cgo命令go build -buildmode=c-archive test.go之后我收到头文件并尝试通过命令gcc -g -pthread main.c test.a -o main将其链接到我的c项目中,所有编译和链接都是可疑的但在运行时我收到下一个错误:{ {1}}想法是在c中接收指向DB的指针,做一些工作,当DB不需要关闭DB时。

1 个答案:

答案 0 :(得分:0)

正如JimB所说;这可能不起作用(因为某种原因,它被称为unsafe)。即使你设法将指针强制转换为C可以使用的东西,也存在很大的风险,因为Go中的垃圾收集可能会释放底层资源,因为Go不知道{{1}中的用法}

原始答案

我认为C的签名应为:open_db

变量func open_db(path string) (unsafe.Pointer, error)应转换为db;天真地像这样:unsafe.Pointer但我不知道在这种情况下数据库实现的细节。

您的return unsafe.Pointer(db), err函数可能还需要接受close_db而不是unsafe.Pointer

请参阅:https://golang.org/cmd/cgo/