2

目前我正在使用 Cgo 从 Go 调用 C 函数。我正在尝试在 Go中重新创建“阅读照片”示例。

然而,一个关于 C 函数的函数需要一个int* len参数(额外的问题;是否与 相同int *len?)。当我读到这篇文章时,这是一个指向整数的指针。有问题的函数是ccv_writelibccv 库的。它的完整签名是:

int ccv_write(ccv_dense_matrix_t* mat, char* out, int* len, int type, void* conf)

相关代码片段如下:

type Image struct {
    image *C.ccv_dense_matrix_t
}

func main() {
    image := new(Image)

    /* ... snip ... */

    dst := C.CString("black_and_white_painting.jpg")
    defer C.free(unsafe.Pointer(dst))
    x := 0 // <- perhaps var x int ?
    C.ccv_write(image.image, dst, (*C.int)(&x), C.CCV_IO_PNG_FILE, 0)
}

上面的示例生成以下编译时错误:cannot convert &x (type *int) to type *_Ctype_int

关于如何传递正确论点的任何想法?

4

3 回答 3

9

这似乎对我有用:

package main

/*

void foo(int *len) { *len = 1234; }

*/
import "C"

func main() {
        var x C.int
        C.foo(&x)
        println(x)
}
于 2012-11-16T14:07:21.987 回答
7

这里的问题是你有两种不同的类型。你有一个int由你的 Go 编译器C.int定义的,由你的 C 编译器定义的。根据编译器和架构,这些可能是相同的大小。但是,它的大小很可能int是 64 位和C.int32 位。

为了让编译器强制执行类型安全,它要求您进行显式转换或在初始化时定义类型。

在您的示例中,您执行以下操作:x := 0. 这与x := int(0). int是暗示的。相反,您可以执行x := C.int(0).

但是,我认为“更清洁”的方法是做 jnml 推荐的:var x C.int. 这完全一样,但看起来更好。


稍后,您很可能希望将其转换C.intint. 这很容易通过转换来完成。

y := int(x)

这将转换x为一个int,然后将该值复制到新初始化的变量y中。


Bonus Anwser:int* len确实与int *len

于 2012-11-16T17:38:26.010 回答
3

你需要一个unsafe.Pointer演员表。

C.ccv_write(image.image, dst, (*C.int)(unsafe.Pointer(&x)), C.CCV_IO_PNG_FILE, 0)
于 2012-11-16T14:53:09.933 回答