加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang之cgo一---go与C基本类型转换

发布时间:2020-12-16 19:17:34 所属栏目:大数据 来源:网络整理
导读:??在嵌入式开发中总少不了和C/C++打交道,而在开发中也总有某些需求要用到某些其他工具的特性,比如go语言。 Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。 Go语言的语法接

??在嵌入式开发中总少不了和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 -->  uint32
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 = %dn",(*(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 nulln"); return ; } fprintf(stdout,"imgPath = %sn",imgInfo->imgPath); fprintf(stdout,"format = %dn",imgInfo->format); fprintf(stdout,"width = %dn",imgInfo->width); } */
import "C"

import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    fmt.Println("----------------Go to C---------------")
    fmt.Println(C.char('Y'))
    fmt.Printf("%cn",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
总结

??在基本类型中,C和go之间的类型转换还是比较方便的。但是区分字符串和字符数组是不同的类型。其中有个很重要的转换:void * -> unsafe.Pointer

https://golang.org/cmd/cgo/
https://zh.wikipedia.org/wiki/Go#cite_note-6

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读