golang之cgo⼀---go与C基本类型转换
在嵌⼊式开发中总少不了和C/C++打交道,⽽在开发中也总有某些需求要⽤到某些其他⼯具的特性,⽐如go语⾔。
Go语⾔专门针对多处理器系统应⽤程序的编程进⾏了优化,使⽤Go编译的程序可以媲美C或C++代码的速度,⽽且更加安全、⽀持并⾏进程。
Go语⾔的语法接近C语⾔,但是对于变量的声明是不同的,其他语法不同之处是For循环和if判断语句不需要⽤⼩括号括起来。
Go语⾔⽀持垃圾回收功能。
与C++相⽐,Go语⾔并不包括如异常处理、继承、泛型、断⾔、虚函数等功能,但增加了slice型、并发、管道、垃圾回收、接⼝(interface)等特性的语⾔级⽀持。
当前有两个Go语⾔的编译器的分⽀。官⽅编译器gc和gccgo。官⽅编译器⽀持跨平台编译(但不⽀持CGO)
go还可以嵌⼊C代码,但是不可以嵌⼊C++代码,当然也可以通过某些⽅式调⽤C++ API(如SWIG),本⽂主要讲CGO。怎么嵌⼊C或者调⽤动态库就简单略过了,主要注意下:
可以⽤注释符//和/**/包围C代码
import “C” 和包含C代码之间是没有空⾏的
动态库的导⼊和编译选项通过LDFLAGS、CFLAGS/CXXFLAGS来设置
还可以⽤pkg-config #cgo pkg-config : xxxxname
编译宏定义指定#cgo CFLAGS: -DNDEBUG -DXXXX=2
今天先看看go和c之间的类型转换:
char --> C.char --> byte
signed char --> C.schar --> int8
unsigned char --> C.uchar --> uint8
short int --> C.short --> int16
short unsigned int --> C.ushort --> uint16
int --> C.int --> int
unsigned int --> C.uint --> uint32cstring转为int
long int --> C.long --> int32 or int64
long unsigned int --> C.ulong --> uint32 or uint64
long long int --> C.longlong --> int64
long long unsigned int --> C.ulonglong --> uint64
float --> C.float --> float32
double --> C.double --> float64
wchar_t --> C.wchar_t -->
void * -> unsafe.Pointer
编程测试:
package main
/*
#include <stdio.h>
#include <stdlib.h>
char ch = 'M';
unsigned char uch = 253;
short st = 233;
int i = 257;
long lt = 11112222;
float f = 3.14;
double db = 3.15;
void * p;
char *str = "const string";
char str1[64] = "char array";
void printI(void *i)
{
printf("print i = %d\n", (*(int *)i));
}
struct ImgInfo {
char *imgPath;
int format;
unsigned int width;
unsigned int height;
};
void printStruct(struct ImgInfo *imgInfo)
{
if(!imgInfo) {
fprintf(stderr, "imgInfo is null\n");
return ;
}
fprintf(stdout, "imgPath = %s\n", imgInfo->imgPath);
fprintf(stdout, "format = %d\n", imgInfo->format);
fprintf(stdout, "width = %d\n", imgInfo->width);
}
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
fmt.Println("----------------Go to C---------------")
fmt.Println(C.char('Y'))
fmt.Printf("%c\n", C.char('Y'))
fmt.Println(C.uchar('C'))
fmt.Println(C.short(254))
fmt.Println(C.long(11112222))
var goi int = 2
// unsafe.Pointer --> void *
cpi := unsafe.Pointer(&goi)
C.printI(cpi)
fmt.Println("----------------C to Go---------------")
fmt.Println(C.ch)
fmt.Println(C.uch)
fmt.Println(C.st)
fmt.Println(C.i)
fmt.Println(C.lt)
f := float32(C.f)
fmt.Println(reflect.TypeOf(f))
fmt.Println(C.f)
db := float64(C.db)
fmt.Println(reflect.TypeOf(db))
fmt.Println(C.db)
// 区别常量字符串和char数组,转换成Go类型不⼀样
str := C.GoString(C.str)
fmt.Println(str)
fmt.Println(reflect.TypeOf(C.str1))
var charray []byte
for i := range C.str1 {
if C.str1[i] != 0 {
charray = append(charray, byte(C.str1[i]))
}
}
fmt.Println(charray)
fmt.Println(string(charray))
for i := 0; i < 10; i++ {
imgInfo := C.struct_ImgInfo{imgPath: C.CString("../images/xx.jpg"), format: 0, width: 500, height: 400} defer C.free(unsafe.Pointer(imgInfo.imgPath))
C.printStruct(&imgInfo)
}
fmt.Println("----------------C Print----------------")
}
输出结果:
----------------Go to C---------------
89
Y
67
254
11112222
----------------C to Go---------------
77
253
233
257
11112222
float32
3.14
float64
3.15
const string
[64]main._Ctype_char
[99 104 97 114 32 97 114 114 97 121]
char array
----------------C Print----------------print i = 2
imgPath = ../images/xx.jpg format = 0
width = 500
imgPath = ../images/xx.jpg format = 0
width = 500
imgPath = ../images/xx.jpg format = 0
width = 500
imgPath = ../images/xx.jpg format = 0
width = 500
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论