integer division in Go called from C

核能气质少年 提交于 2019-12-05 17:16:15

You need to link using gccgo and not with normal gcc. Normal gcc doesn't know that it ought to link against the go runtime (libgo).

Depending on your configuration, you might also need to specify where the runtime library can be found. For example by embedding it statically or by making it available in the LD_LIBRARY_PATH environment variable. Example:

gccgo -static-libgo calc.o calcc.o -o main

For more information, check Setting up and using gccgo.

I believe your method of using __asm__ is gccgo specific (I've never seen it before).

The standard way to export Go functions to C is via an "//export name" comment in the Go code.

Further, standard Go<->C via cgo requires that C code is linked into Go and Go's main runs and not the other way around. This is so that the Go runtime is fully running. Otherwise goroutines, the garbage collector, etc would not be running. Of course Go's main could just be a simple call to a C pseudo-main function that does all the work and calls back into Go only as needed.

Given these points a small example of what you tried using standard cgo and fully go build-able is this:

calc.go:

package main

// /* could be in a declared in a header file instead */
// extern void pseudo_main(void);
import "C"

//export Add
func Add(a, b int) int {
    return a + b
}

// … etc …

//export Div
func Div(a, b int) int {
    return a / b
}

// Main needs to be Go so that the go runtime
// gets started so you can use goroutines, the
// garbage collector, etc,etc.
//
// It can just be a trivial call into a C main like
// function.
func main() {
    C.pseudo_main()
}

and calc.c:

#include <stdio.h>
#include "_cgo_export.h" // file auto-generated by cgo from Go's "//export func" comments

// passing argc, argv, envp like arguments
// if desired is left as an excersise :)
void pseudo_main(void) {
    int x, y, z;

    printf("Hello from C\n");
    x = 42;
    y = 6;
    z = Add(x, y);
    printf("%d + %d = %d\n", x, y, z);
    z = Div(x, y);
    printf("%d / %d = %d\n", x, y, z);
}

building and running (on a Unix like host):

% go build -o calc
% ./calc

Note: normally you wouldn't use -o, you'd let the tool pick the name based on package or directory name. I've used -o here to list exact and repeatable commands without specifying what directory the files are in. Further note, for Microsoft Windows it would be different. Also, if you're interested in what goes on behind the scenes with cgo, try go build -x.

output:

Hello from C
42 + 6 = 48
42 / 6 = 7

gist.github.com

See also: The Go Blog: C? Go? Cgo!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!