CGO 中对C语言的void *和void **的处理

CGO 中对C语言的void *void **的处理

1. void *unsafe.Pointer

  • CGO中的 unsafe.Pointer与C语言中的 void *是对应的
  • Go中的结构体如果要传入 C语言的某个函数作为参数, 可以使用 unsafe.Pointer来转化
package main

/*

//假设这段定义在外部C源码中对cgo不可见
//typedef struct User {
//	int id;
//	int age;
//	int number;
//} User;



static void User_SetId(void *user, int id) {
	((User *)user)->id = id;
}

static void User_SetAge(void *user, int age) {
	((User *)user)->age = age;
}

static void User_SetNumber(void *user, int number) {
	((User *)user)->number = number;
}
*/
import "C"

import (
	"fmt"
	"unsafe"
)

type User struct {
	Id int32
	Age int32
	Number int32
}

func main() {
	var user User

	pointer := unsafe.Pointer(&user)

	C.User_SetId(pointer, C.int(1))
	C.User_setAge(pointer, C.int(25))
	C.User_setNumber(pointer, C.int(10001))

	fmt.Println(user)	

}

2. 对应的 void **只需要在现有的 void *类型(CGO中的unsafe.Pointer)的对象上取地址就可以了

package main
/*
typedef struct User {
	int id;
	int age;
	int number;
} User;
static void createUser(void **pUser) {
	if(pUser) *pUser = malloc(sizeof(User))
}


*/
import "C"

import (
	"fmt"
	"unsafe"
)

type User C.User

func main() {

	pointer := unsafe.Pointer(nil)

	C.createUser(&pointer)

	user := (*User)(pointer)

	fmt.Println(user)
}

你可能感兴趣的:(Go,CGO)