cgo 有限制不能返回 []byte:

A Go function called by C code may not return a Go pointer (which implies that it may not return a string, slice, channel, and so forth).

但是可以返回 unsafe.Pointer,例如用 bytes.Title 为例,可以这样包装一下:

//export Title
func Title(bs []byte) unsafe.Pointer {
	return C.CBytes(bytes.Title(bs))
}

编译会生成 so 和头文件,其中头文件有声明:

typedef GoInt64 GoInt;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

extern void* Title(GoSlice bs);

调用的时候搞一个 GoSlice 出来就可以了:

GoSlice input = {
    .data = malloc(sizeof(char) * 12),
    .len = 12,
    .cap = 12,
};

memcpy(input.data, "hello world", 12);

char *result = Title(input);
printf("%s\n", result);

free(result); // Hello World