CGO of Go language learning (Golang and C languages call each other)

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

Life goes on and on go Go go!!!

Almost all programming languages have a C-language shadow, and of course Golang is no exception. You can see that the founders of Golang have a close connection with C language. All, Golang and C-language mutual invocation is also rightfully.

What is the occasion to use go and C interoperability?
The following address gives the answer: http://tonybai.com/2012/09/26/interoperability-between-go-and-c/
1. To improve the performance of local code, replace some go code with C. C is to go, like a compilation of C.
2, too Go memory GC performance is not enough, you manually manage the application memory.
3, the implementation of some library go Wrapper. For example, the C version of OCI provided by Oracle, but Oracle does not provide the go version and the protocol details of the connection db, so it can only be packaged in C OCI version to provide go developer use.
4, go export function for C developers to use (currently this need should be very rare).

Cgo

Cgo enables the creation of GO packages that call C code.

Cgo lets Go packages call C code. Given a Go source file written with some special features, CGO outputs Go and C files, can is combined into a single G O package.

Don't misunderstand this, CGO is not a package, we just need to import "C" just fine.

Package unsafe

Introduce the unsafe package by the way.
Package unsafe contains operations that step around the type safety of Go programs.

Packages that import unsafe may non-portable and is not protected by the Go 1 compatibility guidelines.

Pointer type:

* Type: normal pointer, used to pass object address, cannot be pointer operation.

Unsafe. Pointer: Generic pointer type for converting different types of pointers and not for pointer operations.

UIntPtr: For pointer arithmetic, GC does not take uintptr as pointer, UIntPtr cannot hold object. The target of the UIntPtr type is recycled.

Unsafe. Pointer can be converted to and from normal pointers.
Unsafe. Pointer can be converted to and from UIntPtr.

That means unsafe. Pointer is a bridge that allows arbitrary types of pointers to be converted to each other, or any type of pointer can be converted to UINTPTR for pointer operation.

Golang calling C language

Directly on the code:

package  Main//typedef int (*INTFUNC) ();  // //int  //Bridge_int_func (intfunc f)  //{ //return f ();  //}  // //int fortytwo ()  //{ //return;  //}  import   "C"  import   "FMT"  func  Main () {f: = C.intfunc (c.fortytwo) fmt. Println (int  (C.bridge_int_func (f))}  

If the compilation encounters an error:
Cc1.exe:sorry, Unimplemented:64-bit mode not compiled in
Note that you are using a 64 Golang and you are using a 32-bit mingw, so you need to download the 64-bit MINGW and configure the environment variables.

Output:
42

Here are some of the more difficult:

package  Main//typedef int (*INTFUNC) ();  // //int  //Bridge_int_func (intfunc f)  //{ //return f ();  //}  // //int fortytwo ()  //{ //return;  //}  import   "C"  import   "FMT"  func  Main () {f: = C.intfunc (c.fortytwo) fmt. Println (int  (C.bridge_int_func (f))}  

Is it a bit of a circle, and what's the difference between this and the code above? But when you compile:
Could not determine kind of name for C.bridge_int_func
Could not determine kind of name for C.fortytwo
Could not determine kind of name for C.intfunc

Remember that there is no blank line between the comment and the import "C"

Using data types in the C language in Golang

Numeric Type
In go, you can access C native numeric types in the following ways:

C.char,
C.schar (signed Char),
C.uchar (unsigned char),
C.short,
C.ushort (unsigned short),
C.int, c.uint (unsigned int),
C.long,
C.ulong (unsigned long),
C.longlong (Long Long),
C.ulonglong (unsigned long),
C.float,
C.double

pointer type
The pointer type of the native numeric type can be preceded by the go syntax in front of the type , such as Var P *c.int. void is special and is indicated by the Unsafe.pointer in go. Any type of pointer value can be converted to unsafe. Pointer type, while unsafe. The pointer type value can also be converted to a pointer value of any type. Unsafe. Pointer can also be converted to and from the UIntPtr type. Due to unsafe. The pointer pointer type cannot do arithmetic operations, and after conversion to uintptr, arithmetic operations can be performed.

* String Type *
There is no formal string type in C, the string is represented in C with an array of characters with the trailing ' s ', whereas in Go, the string type is a primitive type, so in both languages interoperability is bound to be a conversion of the string type.

With the c.cstring function, we can convert the string type of go to the "string" type of C and then pass it to the C function. As we used in the opening example of this article:

S: = "Hello cgo\n"
CS: = c.cstring (s)
C.print (CS)

Array Type
The array in the C language differs greatly from the array in the Go language, which is a value type, while the former and the pointer in C are freely convertible in most cases. There seems to be no direct transformation between the two in the present, nor is official documentation. But we can do this by writing a conversion function, converting the array of C to Go's slice (since the array in Go is a value type, its size is static, the conversion to slice is more general), here is an example of an integer array conversion:

 PackageMain//int carray[] = {1, 2, 3, 4, 5, 6, 7};Import "C"Import "FMT"Import "unsafe"funcCarraytogoarray (CArray unsafe. Pointer, sizeint) (Goarray []int) {p: =UIntPtr(CArray) forI: =0; i < size; i++ {J: = * (*int) (unsafe. Pointer (p)) Goarray =Append(Goarray, j) p + = unsafe. Sizeof (J)}return}funcMain () {goarray: = Carraytogoarray (unsafe. Pointer (&c.carray[0]),7) FMT. Println (Goarray)}

Calling the Golang code in C

Directly on the code:

package main/*extern void myprint(int i);void dofoo(void) {    int i;    for (i=0;i<10;i++) {        myprint(i);    }}*/import"C"import"fmt"//export myprintfunc myprint(i C.int) {    fmt.Printf("i = %v\n"uint32(i))}func DoFoo() {    C.dofoo()}func main() {    DoFoo()}

Unfortunately, there was an error:
c:\users\wangs\appdata\local\temp\go-build603641814\cgo_obj\main.cgo2.o:in function dofoo':
D:/go_workspace/src/cgo/main.go:6: multiple definition of
Dofoo '
C:\users\wangs\appdata\local\temp\go-build603641814\cgo_obj_cgo_export.o:d:/go_workspace/src/cgo/main.go:6: First defined here
Collect2.exe:error:ld returned 1 exit status

Modify, split into two files:
Main.go

package main/*extern void myprint(int i);void dofoo(void) {    int i;    for (i=0;i<10;i++) {        myprint(i);    }}*/import"C"func main() {    C.dofoo()}

Foo.go:

package mainimport"C"import"fmt"//export myprintfunc myprint(i C.int) {    fmt.Printf("i = %v\n"uint32(i))}

Reference Links:
http://tonybai.com/2012/09/26/interoperability-between-go-and-c/

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.