CGO开发中必须注意的一个注释陷阱

CGO开发中,如果有注释使用不当,你会遇到一些奇奇怪怪的问题。比如下方的一个使用示例就是一个典型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

/**
#include <stdio.h>
#include <sys/utsname.h>
struct utsname name;
void uname_main() {
uname(&name);
printf("uname sysname: %s\n", name.sysname);
printf("uname nodename:%s\n", name.nodename);
printf("uname release: %s\n", name.release);
printf("uname version: %s\n", name.version);
printf("uname machine: %s\n", name.machine);
}
*/
import "C"
import (
"sync"
"unsafe"

log "github.com/Sirupsen/logrus"
)

var (
unameOnce sync.Once
)

type AFormatter struct{}

func (f *AFormatter) Format(entry *log.Entry) ([]byte, error) {
return []byte(entry.Message), nil
}

func init() {
log.SetFormatter(&AFormatter{})
}

//noinspection GoAddressOperators
func main() {
unameOnce.Do(func() {
C.uname_main()
})
log.Printf("C.sysname: %v", C.GoString((*C.char)(unsafe.Pointer(&C.name.sysname))))
log.Printf("C.nodename: %v", C.GoString((*C.char)(unsafe.Pointer(&C.name.nodename))))
log.Printf("C.release: %v", C.GoString((*C.char)(unsafe.Pointer(&C.name.release))))
log.Printf("C.version: %v", C.GoString((*C.char)(unsafe.Pointer(&C.name.version))))
log.Printf("C.machine: %v", C.GoString((*C.char)(unsafe.Pointer(&C.name.machine))))
}

这段代码想使用CGO来调用uname,获取计算机的一些uname信息,我们来编译一下看看输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
# command-line-arguments
In file included from onething.net/onecloud/test/main.go:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/stdio.h:64:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/_stdio.h:71:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/_types.h:27:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/sys/_types.h:33:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/machine/_types.h:32:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/i386/_types.h:37:1: error: expected identifier or '('
typedef __signed char __int8_t;
^
1 error generated.

Compilation finished with exit code 2

这段代码,如果使用C语言来直接编译和输出是完全没有问题的,输出如下:

1
2
3
4
5
uname sysname: Darwin
uname nodename:XXX-MacBook-Pro.local
uname release: 18.0.0
uname version: Darwin Kernel Version 18.0.0: Wed Aug 22 20:13:40 PDT 2018; root:xnu-4903.201.2~1/RELEASE_X86_64
uname machine: x86_64

解决这个问题很简单,就是把多余的星号去掉!!

正确的输出:

是不是很惊喜,是不是很意外?!查了我好久的时间… <哭泣>.png