美文网首页Golang语言社区
CGo--go语言与C语言互相调用

CGo--go语言与C语言互相调用

作者: 吃猫的鱼0 | 来源:发表于2018-01-04 10:51 被阅读8次

    在以前的认识中,不同语言的相互交流大概只能靠网络依靠json来传递数据。下面来了解一个新的方法:嵌入式开发

    首先巴拉巴拉一下C++吧

    • C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程

    这是C++简介上对C++的定义。(以前一直以为c++是面向过程的语言)

    • C++ 被认为是一种中级语言,它综合了高级语言和低级语言的特点。
    • C++ 进一步扩充和完善了 C 语言,最初命名为带类的C,后来在 1983 年更名为 C++。
    • C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。
    • 最重要的是c++没有自动垃圾回收机制

    golang调用C++

    1.给电脑安装MinGW(即gcc)

    • 下载

    在网上查好多人都没有说这一步,没有安装gcc会报以下错,没接触的人一下就买有眉目了

    "gcc": executable file not found in %PATH%
    

    因为这个公司是美国企业,下载这个东西不是很容易,找了好久发现一个离线的包,点击获取

    • 环境变量配置

    详细环境变量配置参考

    2.上代码

    • 外部调用

    foo.c

    里面有c调用了go的代码

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    typedef UINT_PTR(__stdcall* GIRL_PROC)(int);
    typedef UINT_PTR(__cdecl* GIRL_PROC_CDECL)(int);
    
    UINT_PTR Func1(int n, GIRL_PROC gp)
    {
        printf("我是在go语言中嵌套的c++语言\n");
        if (gp == NULL)
        {
            return 0;
        }
        return (*gp)(n);//这里其实是c调用了go的代码
    }
    
    UINT_PTR Func2(int n, GIRL_PROC_CDECL gp)
    {
        if (gp == NULL)
        {
            return 0;
        }
        return (*gp)(n);
    }
    

    main.go

    里面有go调用了c的代码

    package main
    
    import (
        "fmt"
        "syscall"
        "unsafe"
    )
    
    // #include <stdio.h>
    // #include <stdlib.h>
    // #include "foo.c"
    import "C"
    
    func GirlProc(n int32) int32 {
        return n + 97
    }
    
    func main() {
        gp := syscall.NewCallback(GirlProc)
        gop := (*[0]byte)(unsafe.Pointer(gp))
        var t C.UINT_PTR = C.Func1(C.int(29), gop)//这里go调用了c的代码
        fmt.Println("t",t) // 126
    }
    
    • 内部调用

    内部调用和外部调用有点不同就是内部调用将c语言卸载了go语言里面

    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)",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----------------")
    }

    相关文章

      网友评论

        本文标题:CGo--go语言与C语言互相调用

        本文链接:https://www.haomeiwen.com/subject/vxtrnxtx.html