dongyidao1461 2015-08-25 23:04
浏览 44
已采纳

在现有的C项目中使用Go代码

Ever since Go 1.5 came out, I started taking another look at how I could integrate it into an existing project of mine.

The project's codebase is written entirely in C for low level access to to hardware and other fun stuff. However, some of the higher level things are tedious, and I would like to start writing them in a higher level language (Go)

Is there any way I can call Go code from a C program? I installed Go 1.5, which added -buildmode=c-archive (https://golang.org/s/execmodes) which I am trying to get working.

However, I can't seem to get Go to generate the appropriate header files to allow my project to actually compile. When I generate the archive, I see the function in the exported symbols (using objdump), but without the header files to include gcc complains about the function not existing (as expected)

I'm quite new to Go - however, I love the language and would like to make use of it. Is there any idiomatic way ("idiomatic" gets used a lot in the world of Go I see...) to get this to play nicely with each other?

The reason I asked this question and specifically mentioned Go 1.5 is that according to this document, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke Go 1.5 added support for non-Go programs to call Go code. Specifically, mentioned under the section "Go code linked into, and called from, a non-Go program"

  • 写回答

1条回答 默认 最新

  • drs7798 2015-08-26 02:56
    关注

    To build an archive callable from C, you will need to mark them as exported CGo symbols.
    For example, if I create a file foo.go with the following contents:

    package main
    
    import (
        "C"
        "fmt"
    )
    
    //export PrintInt
    func PrintInt(x int) {
        fmt.Println(x)
    }
    
    func main() {}
    

    The important things to note are:

    • The package needs to be called main
    • You need to have a main function, although it can be empty.
    • You need to import the package C
    • You need special //export comments to mark the functions you want callable from C.

    I can compile it as a C callable static library with the following command:

    go build -buildmode=c-archive foo.go
    

    The results will be an archive foo.a and a header foo.h. In the header, we get the following (eliding irrelevant parts):

    ...
    typedef long long GoInt64;
    ...
    typedef GoInt64 GoInt;
    ...
    extern void PrintInt(GoInt p0);
    ...
    

    So that's enough to call the exported function. We can write a simple C program that calls it like so:

    #include "foo.h"
    
    int main(int argc, char **argv) {
        PrintInt(42);
        return 0;
    }
    

    We can compile it with a command like:

    gcc -pthread foo.c foo.a -o foo
    

    The -pthread option is needed because the Go runtime makes use of threads. When I run the resulting executable it prints 42.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办