go cgo struct


原文链接: go cgo struct

对于CGO来说,方式

typedef struct libfacedetection_capi_face_t libfacedetection_capi_face_t;
typedef struct libfacedetection_capi_result_t libfacedetection_capi_result_t;

struct libfacedetection_capi_face_t {

int x;
int y;
int w;
int h;
int neighbors;
int angle;

};

现代所有主流操作系统几乎都是用 C 语音实现的,几乎所有高级语言都能调用 C 语言,例如 PHP 可以调用 C 语言写的 PHP 扩展,Python 也可以调用 C 语言实现的 Python 扩展。 Golang 语言也不例外。

Golang 通过 CGO 机制能很方便的调用 C 语言。本文介绍一下如何在 Go 中调用稍稍复杂一点 C 函数,例如: char* f(int, int*)

首先看一个最简单的例子,将 Golang 中的一个字符串传入 C 函数中:

package main

import "C"

import "unsafe"

func main() {
    s := "Hello Cgo"
	cs := C.CString(s)                // golang字符串转换成 char * ;原理是在C中通过 malloc 分配c内存,并将字符串复制过去
	defer C.free(unsafe.Pointer(cstr))
    C.print(cs)
}

注意:
上述程序中的关键语句cs := C.CString(s)是将一个 Golang 的字符串转换为 C 语言字符串,
该 C 语言字符串是由 C 函数 malloc 从堆中分配的,因此后续需要调用 C.free 释放内存。

2. 函数调用

然后,我们看看如何调用一个复杂一点的 C 函数?例如: char* f(int, int*) ,返回一个char*指针,并且有一个参数也是返回值int*。请直接看下面的例子:

package main

import "C"
import "unsafe"
import "fmt"

func main() {
	rlen := C.int(0)    //返回C中的int变量
	len := 10
	cstr := C.xmalloc(C.int(len), &rlen)
	defer C.free(unsafe.Pointer(cstr))

	gostr := C.GoStringN(cstr, rlen)   // cstring 转换成 gostring
	fmt.Printf("retlen=%v\n", rlen)
	println(gostr)
}

xmalloc函数的第二个参数是int*,这里设计为一个输入、输出参数。我们在 Golang 中使用 C.int 类型的指针就可以; 其返回值是一个char*
在 Golang 中就是 *C.char,由于返回值是指针,其内存由 malloc 分配,因此需要在 Golang 中对其内存进行释放。

3. 结构体

再然后,我们看看如何调用一个返回结构体的 C 函数?例如:struct MyString xmalloc(int len)。请看示例代码:

package main

import "C"
import "unsafe"
import "fmt"

func main() {
	len := 10
	str := C.xmalloc(C.int(len))
	defer C.free(unsafe.Pointer(str.s))
	gostr := C.GoStringN(str.s, str.len)
	fmt.Printf("retlen=%v\n", str.len)
	println(gostr)
}

参考

  1. http://blog.golang.org/c-go-cgo
  2. https://golang.org/cmd/cgo/
`