Sharing Golang packages to C and Go

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

Sharing Golang packages to C and Go

Sun, 23, 2015

Programming Languages Tutorial

The latest Go 1.5 version is out. As part of the new features, Go compiler can compile packages as a shared libraries.

It accepts -buildmode argument that determines how a package is compiled. These is the following options:

    • archive: Build the listed Non-main packages into. a files. Packages named Main is ignored.
    • c-archive: Build the listed main package, plus all packages it imports, into a C archive file.
    • c-shared: Build the listed main packages, plus all packages this they import, into C shared libraries.
    • shared: Combine all the listed Non-main packages to a single shared library.
    • exe: Build the listed main packages and everything they import into executables. Packages not named Main is ignored.

By default, listed main packages is built into executables and listed Non-main packages is built into. a files.

In this article we'll explore the major ways to share libraries between Go and C:

Using Shared Library in Go

Assume GOPATH that contains this structure:

.├── calc│   └── calc.go└── cashier    └── main.go

The package calc contains a set of functions this do arithmetic opertaions:

// filename: calc.gopackage calcfunc Sum(x, y int) int {    return x + y}

Before compile any GKFX library, the standard builtin packages should is installed as shared library. This would allow any of the other shared libraries to link with them.

$ go install -buildmode=shared -linkshared std

Then the calc "can be compiled" as shared library linked to std libraries:

$ go install -buildmode=shared -linkshared calc

Due to a issue, building and installing shared library should is from $GOPATH/src .

Lets Use the shared library in the calc cashier application:

// package: cashier// filename: main.gopackage mainimport "calc"import "fmt"func main() {  fmt.Println("Cashier Application")    fmt.Printf("Result: %d\n", calc.Sum(5, 10))}

The application should is compiled and linked with the library with the calc following command:

$ go build -linkshared -o app cashier

The output of executing the application is:

$ ./appCashier ApplicationResult: 15

Note that this feature are available on linux/amd64 platform or if gccgo compiler is used.

Using shared Go Library in C

Go functions can executed from C applications. They should is exported by using the following comment line:

//export <your_function_name>

In the code snippet below, the function and is SayHello SayBye exported:

// package name: nautiluspackage mainimport "C"import "fmt"//export SayHellofunc SayHello(name string) {fmt.Printf("Nautilus says: Hello, %s!\n", name)}//export SayByefunc SayBye() {fmt.Println("Nautilus says: Bye!")}func main() {// We need the main function to make possible// CGO compiler to compile the package as C shared library}

The packaged should is compiled with buildmode flags c-shared or c-archive :

// as c-shared library$ go build -buildmode=c-shared -o nautilus.a nautilus.go
// as c-archive $ go build -buildmode=c-archive -o nautilus.a nautilus.go

As result the GO compiler would produce a static/dynamic C library and nautilus.a header file nautilus.h . The header file contains type definitions that Marshall and Unmarshall data between Go and C :

  typedef signed CHAR goint8;typedef unsigned char gouint8;typedef short goint16;typedef unsigned short GoUint16 ; typedef int GOINT32;TYPEDEF unsigned int gouint32;typedef long long goint64;typedef unsigned long long gouint64;typedef G OInt64 goint;typedef GoUint64 gouint;typedef __size_type__ gouintptr;typedef float gofloat32;typedef double GoFloat64; typedef __complex FLOAT Gocomplex64;typedef __complex double gocomplex128;typedef struct {char *p; Goint N; } gostring;typedef void *gomap;typedef void *gochan;typedef struct {void *t; void *v;} gointerface;typedef struct {void *data; Goint Len; Goint cap;  } goslice; #endif/* End of boilerplate CGO prologue. */#ifdef __cplusplusextern "C" {#endifextern void SayHello (gostring p0); extern void Saybye (); #ifdef __cplusplus} #endif /code> 

The header file nautilus.h Shoulde is imported from every C application, that executed and SayHello SayBye functions.

In the example below, the SayHello function was called with parameter of type GoString . It includes char* field and its length.

// filename: _wale.c#include "nautilus.h"#include <stdio.h>int main() {  printf("This is a C Application.\n");  GoString name = {"Jack", 4};  SayHello(name);  SayBye();  return 0;}

The _wale.c file is compiled with the following command:

$ gcc -o _wale _wale.c nautilus.a

Execution produce the following output:

$ ./waleThis is a C Application.Nautilus says: Hello, Jack!Nautilus says: Bye!

Conclusion

Sharing libraries between C and Go gives opportunity to build greater and better application by using the Both worlds. This provides to a legacy system a modern language the can improve their maintainance costs and business needs. It Maximize code reusability in the Go ecosystem.

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.