Add c code to the go package and do not use CGO (GCC is not required)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

If CGO is used in the go code, it must be compiled on the computer according to GCC to compile correctly.

This article shows how to write a package with C to make go call and do not need to use CGO


A need to be aware of:

1. C Code is inherently unsafe

2. GO1 compatibility guarantee does not include C code

3. C function cannot be inline

4. Escape analysis cannot track value passed to C function (Escape analysis: Http://kenwublog.com/jvm-optimization-escape-analysis)

5. The C compiler (5C,6C,8C) does not have the corresponding go compiler optimizations done well, so the generated code may not be as good as the Go Code optimizer

6. C code is PLAN9 style, more similar to C89


B the way to return

The first example is a simple function that returns true: True

void True (bool res) {        res = true;        FLUSH (&res);}

Brief analysis of the various parts of the function:

1. Return value:

The signature of this function true is void True (bool res), C and go interop are implemented by passing parameters on the stack, so the return value of C is required to be void

2 symbols ·

• Is part of Go's package naming system, preceded by the C function name to make the function belong to the current package. You can specify the attribution of this function by the name of the package in front of it, but this will become complicated when your package's naming system is complex, which is not covered in this article.

3. Parameter return

When Go calls C, the arguments and returns are passed to the called C function in the form of arguments.

In the function body of this example, assigning a value of TRUE or false to res is straightforward, but the last line of flush (&res) needs to be explained: Because Res is not used inside this function , The compiler may optimize this assignment (the assignment statement will be erased) and flush is used to ensure that the res is correctly written back to the stack.


C. Forward statement

In order to correctly identify our true function in the go code, we need to write a forward declaration. If there is no forward declaration, the go compiler does not know the existence of this function. This is not associated with the first letter case to make the function visible outside the package

The forward declaration is as follows:

True always returns True.func true () bool
The forward declaration contains the following information: The function True has no arguments and returns a value of type bool. Because this is a normal go function, you can add a comment in front so that it can be displayed with Godoc (the comments in the C function will not be displayed Godoc)

D. Passing parameters to C code

The following will give a function max, which will return the largest of the two int parameters

void Max (IntPtr A, IntPtr b, IntPtr res) {        res = a > b? a:b;        FLUSH (&res);}
Max is similar to the previous true function, the first two arguments are function arguments, and the last parameter is the return value. The return value of a function is not necessarily named Res, but a common usage in the standard library.

A and B are IntPtr types, and this is the C-equivalent of the platform-related int type in Go (X86:int32 x64:int64)

The forward declaration of Max is as follows, and this example allows you to see the corresponding relationship between the parameters and the return values of the go and the parameters in C.

Max returns the maximum of the Integers.func Max (a, b int) int

E. Delivery address

In the first two examples, we pass two parameters to the function and return the copy through the stack. The function call of Go is the value pass, and the C function is called.

In the last example we will pass a pointer to a variable to the C function and change the value by the pointer

void INC (intptr* addr) {        *addr+=1;                Used (addr);}
The INC function gets a pointer to a, dereference and +1,use macro and flush action.

The forward statement is as follows:

INC increments the value of the the integer add address p.func Inc (P *int)

F. All Codes

The test code and test results are as follows:

Ccode.c

#include "runtime.h"//required for GO types like bool and intptr//the Interpunkt indicates so the function belongs to The current//namespace. Without the Interpunkt, the function would is defined in//the global C namespace, inaccessible to your Go package and//p Otentially conflicting with another C function.void True (bool res) {res = true; FLUSH (&res);} IntPtr is equivalent to Go ' s arch specific int typevoid Max (IntPtr A, IntPtr b, IntPtr res) {res = a > b? a:b; FLUSH (&res);} void INC (intptr* addr) {*addr+=1; Used (addr);}

Ccode.go

Package ccode//true always returns True.func True () bool//Max returns the maximum of both Integers.func Max (A, b int) int INC increments the value of the the integer add address p.func Inc (P *int)

Ccode_test.go

Package Ccodeimport "Testing" func testtrue (t *testing. T) {if! True () {T.fatalf ("true (): expected%v got%v", True, True ())}}func Testmax (t *testing. T) {A, B: =, -6if max (A, b)! = a {t.fatalf ("Max (%v,%v): Expected%v, got%v", A, B, a, Max (A, b))}}func Testinc (t *tes Ting. T) {V: = 9000if Inc (&v), v < 9001 {T.fatalf ("INC (9000): expected 9001, got%v", V)}}

Execution Result:
> Go test-v ccode=== run testtrue---pass:testtrue (0.00 seconds) = = = RUN Testmax---pass:testmax (0.00 seconds) = = = R UN testinc---pass:testinc (0.00 seconds) Passok Ccode 0.338s


Summarize

This article briefly explains how to use C to write go packages, the appropriate use of certain situations is more convenient or in the use of assembly language is very important


Test Engineering Package Download:

http://download.csdn.net/detail/varding/6394401

Note: The package main is added, not only the test method but also the method of use

Maybe some friends to Golang understand is not very thorough, compile what still have some doubts, so I put this project package came up, I hope you can test through

There is also a general understanding of the use of Go build, go test, go install, etc.

Download the package of Env.cmd is my daily use, this can add the current package path to Gopath, easy to go build and other commands, can be placed in other engineering root directory directly use, very convenient, recommended collection

Instructions for use:

1. Double-click Env.cmd, the following command is entered in the popup window 2. Test: Go test-v ccode output: = = = Run Testtrue---pass:testtrue (0.00 seconds) = = = Run Testmax---PA Ss:testmax (0.00 seconds) = = = RUN Testinc---pass:testinc (0.00 seconds) Passok      ccode   0.255s3. Install Ccode Library: Go Install CCODE4. Compile: Go build main5. Run: Main.exe







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.