CGO; C函数有int指针参数,如何传递正确的类型?

时间:2012-11-16 13:41:52

标签: go cgo

目前我正在使用Cgo从Go调用C函数。我正在尝试在Go中重新创建'Read a Photo'示例。

然而,C函数中的一个需要int* len参数(奖励问题;与int *len相同吗?)。当我读到这个时,这是一个指向整数的指针。有问题的函数是libccv库的ccv_write。它的完整签名是:

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

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

3 个答案:

答案 0 :(得分:7)

这似乎对我有用:

package main

/*

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

*/
import "C"

func main() {
        var x C.int
        C.foo(&x)
        println(x)
}

答案 1 :(得分:4)

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

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

在您的示例中,您执行:x := 0。这与x := int(0)相同。隐含int。相反,您可以执行x := C.int(0)

但是,我认为“更干净”的方法是做jnml推荐的那样:var x C.int。这完全相同,但看起来更好。


稍后,您很可能希望将C.int转换回int。转换很容易做到这一点。

y := int(x)

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


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

相同

答案 2 :(得分:2)

您需要unsafe.Pointer演员。

C.ccv_write(image.image, dst, (*C.int)(unsafe.Pointer(&x)), C.CCV_IO_PNG_FILE, 0)