douke3335 2015-05-06 09:08
浏览 51
已采纳

在现有C项目上使用Go

I have a program entirely written in C that uses multiple object (.o) files in it. These files are all packed inside an archive file (.a) which, in turn, is used at compile-time of the program's main (.c) file.

I want to write a new file for this project in Go. My idea is to write this .go file and then create an object (.o) file from it. Afterwards, I want to put this object file inside the already mentioned archive (.a) file.

This basically means that I want to call Go functions from a C program. I've read this question, and while it showed me that what I want is possible via GCCGO, it's not 100% clear as to how to do it.

Even with the most basic of tests, I get errors during the linking phase. More specifically, here's one of such basic example:


printString.go

package main

import
(
    "fmt"
)

func PrintString(buff string) int {
    fmt.Printf(buff)
    return 1
}

c_caller.c

#define _GNU_SOURCE
#include <stdio.h>

extern int PrintString(char*) __asm__ ("print.main.PrintString");

int main() {
    char *string_to_pass= NULL;
    asprintf(&string_to_pass, "This is a test.");

    int result= PrintString(string_to_pass);
    if(result) {printf("Everything went as expected!
");}
    else       {printf("Uh oh, something went wrong!
");}

    return result;
}

Compiling

In order to compile the Go file, I used this command:

gccgo -c printString.go -o printString.o -fgo-prefix=print -Wall -Werror -march=native

In order to compile the entire thing, I used this command:

gccgo -o main c_caller.c printString.o -Wall -Werror -march=native

The return message I'm getting is:

/usr/lib64/libgo.so.4.0.0: undefined reference to `main.main'
/usr/lib64/libgo.so.4.0.0: undefined reference to `__go_init_main'
collect2: error: ld returned 1 exit status

Which means that GCCGO's expecting a main function in the Go file instead of the C one.

Using the --static-libgo, -static and -Wl,-R,/path/to/libgo.so's_folder options on the second command yield a different result:

/usr/bin/ld: cannot find -lgo
collect2: error: ld returned 1 exit status

Which makes no sense, since I have the LD_LIBRARY_PATH environment variable properly pointing to libgo.so's folder.


I realize that I'm probably doing something wrong here, but I just can't see what that is. There's next to no examples of GCCGO and its interaction with C out there, and the only reference I could find was this page, which I personally feel like it's not enough.

I ask kindly for some advice on this matter and thank you for your time. :)

  • 写回答

2条回答 默认 最新

  • dsfdf854456 2015-05-06 17:24
    关注

    This may not be what you want, but in Go 1.5, that's coming this August, you'll be able to build C-compatible libraries with the go tool. So with this in your _main.c

    #include <stdio.h>
    
    int main()
    {
        char *string_to_pass = NULL;
        if (asprintf(&string_to_pass, "This is a test.") < 0) {
            printf("asprintf fail");
            return -1;
        }
    
        PrintString(string_to_pass);
        return 0;
    }
    

    and this in your main.go

    package main
    
    import "C"
    import "fmt"
    
    //export PrintString
    func PrintString(cs *C.char) {
        s := C.GoString(cs)
        fmt.Println(s)
    }
    
    func main() {}
    

    You can do, for static library:

    go build -buildmode c-archive -o mygopkg.a
    gcc -o main _main.c mygopkg.a -lpthread
    

    For shared library:

    go build -buildmode c-shared -o mygopkg.so
    LD_RUN_PATH=$(pwd) gcc -o main _main.c mygopkg.so -lpthread
    

    (LD_RUN_PATH is here to make the linker look for the shared library in the same directory you're building.)

    See the Go execution modes design document for more info.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装
  • ¥40 复杂的限制性的商函数处理