zoukankan      html  css  js  c++  java
  • Go与C语言的互操作 cgo

    http://tonybai.com/2012/09/26/interoperability-between-go-and-c/

    // foo.h
     
    int count;
    void foo();
     
    //foo.c
    #include "foo.h"
     
    int count = 6;
    void foo() {
        printf("I am foo!
    ");
    }
     
    //foo.go
    
    package main
     
    // #cgo LDFLAGS: -L ./ -lfoo
    // #include <stdio.h>
    // #include <stdlib.h>
    // #include "foo.h"
    import "C"
    import "fmt“
     
    func main() {
        fmt.Println(C.count)
        C.foo()
    }
    使用静态库
    $> gcc -c foo.c
    $> ar rv libfoo.a foo.o
    [diego@localhost ~/GoWork/src/applycation/testCgo]# go build foo.go
    [diego@localhost ~/GoWork/src/applycation/testCgo]# ./foo 
    6
    I am foo!
    [diego@localhost ~/GoWork/src/applycation/testCgo]# gcc -fPIC -shared -o libfoo.so foo.c
    [diego@localhost ~/GoWork/src/applycation/testCgo]# rm li
    libfoo.a   libfoo.so* 
    [diego@localhost ~/GoWork/src/applycation/testCgo]# rm libfoo.a
    [diego@localhost ~/GoWork/src/applycation/testCgo]# go build fo
    foo*    foo.c   foo.go  foo.h   foo.o   
    [diego@localhost ~/GoWork/src/applycation/testCgo]# go build foo.
    foo.c   foo.go  foo.h   foo.o   
    [diego@localhost ~/GoWork/src/applycation/testCgo]# go build foo.go 
    [diego@localhost ~/GoWork/src/applycation/testCgo]# ./foo 
    6
    I am foo!
    [diego@localhost ~/GoWork/src/applycation/testCgo]#

     http://tonybai.com/2012/09/26/interoperability-between-go-and-c/

    与在Go中使用C源码相比,在C中使用Go函数的场合较少。在Go中,可以使用"export + 函数名"来导出Go函数为C所使用,看一个简单例子:
     
    package main
     
    /*
    #include <stdio.h>
     
    extern void GoExportedFunc();
     
    void bar() {
            printf("I am bar! ");
            GoExportedFunc();
    }
    */
    import "C"
     
    import "fmt"
     
    //export GoExportedFunc
    func GoExportedFunc() {
            fmt.Println("I am a GoExportedFunc!")
    }
     
    func main() {
            C.bar()
    }
     
    不过当我们编译该Go文件时,我们得到了如下错误信息:
     
    # command-line-arguments
    /tmp/go-build163255970/command-line-arguments/_obj/bar.cgo2.o: In function `bar':
    ./bar.go:7: multiple definition of `bar'
    /tmp/go-build163255970/command-line-arguments/_obj/_cgo_export.o:/home/tonybai/test/go/bar.go:7: first defined here
    collect2: ld returned 1 exit status
     
    代码似乎没有任何问题,但就是无法通过编译,总是提示“多重定义”。翻看Cgo的文档,找到了些端倪。原来
     
    There is a limitation: if your program uses any //export directives, then the C code in the comment may only include declarations (extern int f();), not definitions (int f() { return 1; }).
     
    似乎是// extern int f()与//export f不能放在一个Go源文件中。我们把bar.go拆分成bar1.go和bar2.go两个文件:
     
    // bar1.go
     
    package main
     
    /*
    #include <stdio.h>
     
    extern void GoExportedFunc();
     
    void bar() {
            printf("I am bar! ");
            GoExportedFunc();
    }
    */
    import "C"
     
    func main() {
            C.bar()
    }
     
    // bar2.go
     
    package main
     
    import "C"
    import "fmt"
     
    //export GoExportedFunc
    func GoExportedFunc() {
            fmt.Println("I am a GoExportedFunc!")
    }
     
    编译执行:
     
    $> go build -o bar bar1.go bar2.go
    $> bar
    I am bar!
    I am a GoExportedFunc!
     

    Go代码:

    func TestCallback() {
        f1 := syscall.NewCallback(PlusOne)
        f2 := syscall.NewCallbackCDecl(PlusTwo)
        var m uint32 = 20
        var n uint32 = 80
    
        // Func1 __stdcall
        fmt.Println(C.Func1(C.uint(m), (*[0]byte)(unsafe.Pointer(f1)))) // 21
    
        // Func2 __cdecl
        fmt.Println(C.Func2(C.uint(n), (*[0]byte)(unsafe.Pointer(f2)))) // 82
    }
    
    func PlusOne(n uint32) uintptr {
        return uintptr(n + 1)
    }
    
    func PlusTwo(n uint32) uintptr {
        return uintptr(n + 2)
    }

    C.Func1的第二个参数类型为函数,所以要传入一个*[0]byte。   http://studygolang.com/articles/2629

    http://blog.giorgis.io/cgo-examples

  • 相关阅读:
    使用Doxygen生成net帮助文档
    Mac OSX 下配置 LNMP开发环境
    vue相关网站资源收集
    AJAX 相关笔记
    toLocaleDateString()
    前端关于图片的优化
    css 水平垂直居中的方法总结
    Mac下安装Twig模版引擎的方法
    gulp基础使用总结
    js中元素操作的有关内容与对比
  • 原文地址:https://www.cnblogs.com/diegodu/p/5133618.html
Copyright © 2011-2022 走看看