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

har*_*arm 1 go cgo

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

然而,关于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)
}
Run Code Online (Sandbox Code Playgroud)

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

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

zzz*_*zzz 8

这似乎对我有用:

package main

/*

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

*/
import "C"

func main() {
        var x C.int
        C.foo(&x)
        println(x)
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*erg 5

这里的问题是您有两种不同的类型。您有一个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.intint。通过转换很容易做到这一点。

y := int(x)
Run Code Online (Sandbox Code Playgroud)

这将转换xint,然后将该值复制到新初始化的变量中y


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