Cgo:找不到使用带有 const char* 参数的回调的方法

问题描述 投票:0回答:2

我正在使用 Go 使用 Cgo 的 C 库,除了回调之外,一切都很好。该库有一个回调设置器,它采用指向回调函数的指针。回调函数是用Go编写的,并使用Cgo语法导出。

问题:我可以使用

char *
参数创建和导出函数,但不能使用
const char *

代码说明:

测试.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)))
}

测试.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
来获取 C 中的 const 字符串?

go callback cgo
2个回答
7
投票

由于 Go 没有指针修饰符

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

处理此问题的最佳方法是在 C 端使用包装器,将该参数强制转换为

const char*
。在您的情况下,将
myFunc
的定义更改为
void myFunc(char*, int)
就足够了。无论如何,将函数传递给
cb_func
都会起作用,因为将
myFunc
转换为
(*cb_func)(const char*,int)
只会添加类型信息,但不会更改内存布局。


7
投票

我也有同样的问题。对于仍然需要的人来说,一种解决方案是:

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

然后在 go 中使用它作为

data* C.char_t

© www.soinside.com 2019 - 2024. All rights reserved.