Use Go to Existing C Project

I have a program written entirely in C that uses several objects in it (.o). These files are stored in an archive (.a), which, in turn, is used during compilation of the main (.c)program file .

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

This basically means that I want to call Go functions from C program . I read this question , and while it showed me that what I want, perhaps through GCCGO, is not 100% clear how to do this.

Even with the most basic tests, I get errors during the binding phase. More specifically, here is one of these basic examples:


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!\n");}
    else       {printf("Uh oh, something went wrong!\n");}

    return result;
}

Compilation

To compile the Go file, I used this command:

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

To compile all this, I used this command:

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

The returned message that I receive:

/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

This means that GCCGO expects the main function in the Go file instead of C.

Using options --static-libgo, -staticand -Wl,-R,/path/to/libgo.so's_folderfor the second command gives a different result:

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

This does not make sense, since I have an LD_LIBRARY_PATH environment variable pointing correctly to the libgo.so folder.


, , , - , , . GCCGO C , , , , .

.:)

+4
2

, , Go 1.5,, , C- go. _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;
}

main.go

package main

import "C"
import "fmt"

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

func main() {}

:

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

:

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

(LD_RUN_PATH , , .)

. .

+8

, . Go , main. AFAIK, gccgo .

, , go1.5 +, Go.

, , Android gch toolchain -linkmode external, main .

+2

All Articles