【问题标题】:Cgo: can't find way to use callbacks with const char* argumentCgo:找不到使用带有 const char* 参数的回调的方法
【发布时间】:2020-07-20 17:17:19
【问题描述】:

我正在使用来自 Go 的 C 库,使用 Cgo 并且除了回调之外一切都很好。库有回调设置器,它接受指向回调函数的指针。回调函数本身用 go 编写并使用 Cgo 语法导出。
问题:我可以使用char * 参数创建和导出函数,但不能使用const char *

说明代码:
test.go

package main

/*
typedef void (*cb_func)(const char *, int);
void callback(cb_func);
void myFunc(const char *, int);
*/
import "C"
import (
        "fmt"
        "unsafe"
)

//export myFunc
func myFunc(buf *C.char, ln C.int) {
        fmt.Printf("Got: %s\n", C.GoStringN(buf, ln))
}

func main() {
        C.callback((C.cb_func)(unsafe.Pointer(C.myFunc)))
}

test.c

typedef void (*cb_func)(const char *, int);

void callback(cb_func cb) {
        cb("test", 4);
}

来自go build的输出:

In file included from $WORK/test/_obj/_cgo_export.c:2:0:
./test.go:54:13: error: conflicting types for 'myFunc'
./test.go:7:6: note: previous declaration of 'myFunc' was here
 void myFunc(const char *, int);
      ^
/tmp/go-build994908053/test/_obj/_cgo_export.c:9:6: error: conflicting types for 'myFunc'
 void myFunc(char* p0, int p1)
      ^
In file included from $WORK/test/_obj/_cgo_export.c:2:0:
./test.go:7:6: note: previous declaration of 'myFunc' was here
 void myFunc(const char *, int);
      ^

没有const 限定符的代码可以按预期编译和工作。

*C.char 的 insted 可以用来在 C 中获取 const 字符串吗?

【问题讨论】:

    标签: go callback cgo


    【解决方案1】:

    由于 Go 没有指针的 const 修饰符,因此无法从 Go 代码内部转换此行为。 cgo 将始终生成没有 const 修饰符的标头。这也是您的代码无法正确构建的原因:cgo 仅根据它知道的内容创建 myFuncbuf 应该是 char*,而不是 const char*

    处理此问题的最佳方法是在 C 端使用包装器,将该参数转换为 const char*。在您的情况下,将myFunc 的定义更改为void myFunc(char*, int) 就足够了。无论如何,将函数传递给cb_func 将起作用,因为将myFunc 转换为(*cb_func)(const char*,int) 只会添加类型信息,但不会更改内存布局。

    【讨论】:

    • 好的,wrapper 是一个解决方案。但是,现在我直接在 go 文件中重新定义了没有 const 的回调原型(如我上面的示例)。它看起来有点老套,但也可以。
    【解决方案2】:

    我遇到了同样的问题。仍然需要的人的一种解决方案是:

    typedef const char cchar_t
    void myNewFunction(cchar_t* data);
    

    然后在 go 中以 data* C.char_t 使用它

    【讨论】:

    • 错字:在 Go 中使用 *C.cchar_t 而不是 *C.char_t(我建议编辑,但编辑队列已满)
    猜你喜欢
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多