zoukankan      html  css  js  c++  java
  • 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 -->  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 = %d
    ", (*(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
    ");
            return ;
        }
    
        fprintf(stdout, "imgPath = %s
    ", imgInfo->imgPath);
        fprintf(stdout, "format = %d
    ", imgInfo->format);
        fprintf(stdout, "width = %d
    ", imgInfo->width);
    }
    
    */
    import "C"
    
    import (
        "fmt"
        "reflect"
        "unsafe"
    )
    
    func main() {
        fmt.Println("----------------Go to C---------------")
        fmt.Println(C.char('Y'))
        fmt.Printf("%c
    ", 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,  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
    

      

  • 相关阅读:
    基于spec评论作品
    Alpha版发布
    软件工程第七次作业
    软件工程第六次作业
    软件工程第五次作业
    django-rest-framework笔记-序列化篇
    django restframework系列笔记
    rpyc 文件监控
    python subprocess select 读取
    Python 多线程 类和方法
  • 原文地址:https://www.cnblogs.com/adjk/p/9469845.html
Copyright © 2011-2022 走看看