C and Go call each other

Source: Internet
Author: User

C can call go, and go can call C, if it went further, C-->Go-->C or Go-->C-->Go How is the call implemented?

This article uses two simple examples to help you understand these two complex invocation relationships. This article does not deal with the complex data conversion between the two, the official article C? Go? Cgo!, Wiki/cgo and Cmd/cgo have some introductions.

Go-->c-->go

The Go program calls the C-implemented function, and then the C-implemented function calls the GO implementation function.

1. First, we create a new hello.go file:

hello.go
123456789
 Package mainimport"C"import"FMT"//export Hellofromgo func Hellofromgo () {fmt. Printf ("Hello from go!\n")}

It defines a HelloFromGo function, note that the function is a pure go function, and we define its output symbol as HelloFromGo .

2. Then we create a new hello.c file:

hello.c
123456789
#include <stdio.h>#include "_cgo_export.h"int HELLOFROMC () {    printf("Hi from c\n");    //call Go function    Hellofromgo ();    return 0;}

This c file defines a C function helloFromC , inside it calls the function we just defined HelloFromGo .

In this way, we implement the C call Go : C-->Go , below we implement go call C.

3. Finally create a new main.go file:

main.go
1234567891011
 Package Main/*extern int HELLOFROMC (); */import"C"func main () { //call C function C.HELLOFROMC ()}

It invokes the C function implemented in the second step helloFromC .

Run the test for a moment:

123
$ go run. Hi from Chello from go!

As you can see, the expected function call runs normally. The first line is the output of the C function, and the second line is the output of the GO function.

C-->go-->c

The second example shows the functions that the C program calls the go implementation, and then the go implementation function calls the C implementation function.

1. Create a new hello.c file first:

hello.c
123456
#include <stdio.h>int Hellofromc () {    printf("Hi from c\n");    return 0;}

It defines a pure C implementation of the function.

2. Then create a new hello.go file:

12345678910111213141516171819
//Go build-o hello.so-buildmode=c-shared.  Package Main/*extern int HELLOFROMC (); */import"C"import"FMT"  //export Hellofromgofunc Hellofromgo () {fmt. Printf ("Hello from go!\n") C.HELLOFROMC ()}func main () {}

It implements a Go function HelloFromGo , the internal implementation calls the C implementation of the function helloFromC , so that we have implemented Go-->C .

Note The package name is set to package main , and an empty main function is added.

Run go build -o hello.so -buildmode=c-shared . generates a library that can be called by C, which generates hello.so files and files when the command finishes hello.h .

3, finally create a new folder, a name, such asmain

Copy the files and files that you just generated hello.so to the folder and hello.h main main Create a new file in the folder main.c :

main.c
12345678910
#include <stdio.h>#include "hello.h"int main () {    printf ("Use Hello lib from c:\n");       Hellofromgo ();        return 0;}

Run gcc -o main main.c hello.so the build executable file main and run main :

1234
$./mainuse Hello Lib from C:hello from go! Hi from C

The first line of output comes from the main.c second line from the Go function, and the third line comes from hello.c the C function in, so that we implement C-->Go--C the complex call.

C-->Go-->CThe state variable

Let us analyze a special scene in the second step, for the following we distinguish, we give the program mark, remember C1-->Go-->C2 , C2 program modified, add a state variable a , and the function helloFromC will print a the address and value, also will add a one.

hello.c
12345678
#include <stdio.h>int  1;  int Hellofromc () {    printf("Hi from C:%p,%d\n", &a, a++);    return 0;}

Then modify the main.c program so that it is used both by go and C1.helloFromC directly, to see if the pointer is consistent at C1.helloFromC multiple calls, a and a whether the value changes.

Main.c
1234567891011121314151617
#include <stdio.h>#include "hello.h"int main () {    printf ("Use Hello lib from c:\n");       //1. Call C function directly    HELLOFROMC ();    //2. Call the Go function    Hellofromgo ();        //3. Call C function directly    HELLOFROMC ();    return 0;}

It's a thrilling time. Our different ways of compiling produce different results.

1.gcc -o main main.c hello.so

And the second step of the same compilation, compiled main and executed, because hello.so the C1.helloFromC implementation is included, so it can be executed normally.

123456
0 1 0 2 0 3

You can see that a the pointer is the same value, whether through the go function change or through the C function changes are the same variable.

NM to view the generated main symbols:

1234567
NM main                 u _hellofromgo0000000100000000 T __mh_execute_header                 u _hellofromc0000000100000 F10 T _main                 u _printf                 u dyld_stub_binder

URepresents the symbol that is undefined and is linked through a dynamic library.

2.gcc -o main main.c hello.so ../hello.c

We compile the implementation of the direct link hello.c , and then run main :

123456
0 1 0 1 0 2

You can see a that the two variables are different.

NM to view the generated main symbols:

12345678
NM main                 U _hellofromgo0000000100000000 T __mh_execute_header0000000100001020 D _a  0000000100000F10 T _HELLOFROMC0000000100000ec0 T _main                 u _printf                 u dyld_stub_binder

You can see that the _a environment variable is initialized, and _helloFromC the type is T instead U , which represents a global text symbol, which is not the same as the previous step.

Reference documents

    1. https://medium.com/using-go-in-mobile-apps/ Using-go-in-mobile-apps-part-1-calling-go-functions-from-c-be1ecf7dfbc6
    2. https://github.com/ Vladimirvivien/go-cshared-examples
    3. http://golang.org/cmd/cgo
    4. https://gist.github.com/zchee/ B9c99695463d8902cd33
    5. https://medium.com/@liamkelly17/working-with-packed-c-structs-in-cgo-224a0a3b708b
    6. Https://groups.google.com/forum/#!topic/golang-nuts/EhndTzcPJxQ
    7. https://docs.google.com/ document/d/1nr-tqhw_er6goqrsf6t43gghfdelrap0nqss_00rgzq/edit#
    8. https://www.mkssoftware.com/docs/man1/ Nm.1.asp
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.