go share library
http://blog.ralch.com/tutorial/golang-sharing-libraries/
Sharing Golang packages to C and Go
Sun, Aug 23, 2015
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 are the following options:
archive
: Build the listed non-main packages into .a files. Packages named main are 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 that they import, into C shared libraries.shared
: Combine all the listed non-main packages into a single shared library.exe
: Build the listed main packages and everything they import into executables. Packages not named main are ignored.
By default, listed main packages are built into executables and listed non-main packages are built into .a files.
In this article we will explore two major ways to share libraries between Go and C:
Using shared library in Go
Assume that GOPATH
contains this structure:
.
├── calc
│ └── calc.go
└── cashier
└── main.go
The calc
package contains a set of functions that do arithmetic opertaions:
// filename: calc.go
package calc
func Sum(x, y int) int {
return x + y
}
Before compile any shared library, the standard builtin packages should be installed as shared library. This will allow any other shared library to link with them.
$ go install -buildmode=shared -linkshared std
Then the calc
package 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 be from $GOPATH/src
.
Lets use the shared library calc
in the cashier
application:
// package: cashier
// filename: main.go
package main
import "calc"
import "fmt"
func main() {
fmt.Println("Cashier Application")
fmt.Printf("Result: %d\n", calc.Sum(5, 10))
}
The application should be compiled and linked with calc
library with the following command:
$ go build -linkshared -o app cashier
The output of executing the application is:
$ ./app
Cashier Application
Result: 15
Note that this feature is available on linux/amd64
platform or when gccgo
compiler is used.
Using shared Go library in C
Go functions can be executed from C applications. They should be exported by using the following comment line:
//export <your_function_name>
In the code snippet below, the function SayHello
and SayBye
are exported:
// package name: nautilus
package main
import "C"
import "fmt"
//export SayHello
func SayHello(name string) {
fmt.Printf("Nautilus says: Hello, %s!\n", name)
}
//export SayBye
func 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 be 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 will produce a static/dynamic C
library nautilus.a
and 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 GoInt64 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 __cplusplus
extern "C" {
#endif
extern void SayHello(GoString p0);
extern void SayBye();
#ifdef __cplusplus
}
#endif
The header file nautilus.h
shoulde be imported from every C
application that executed SayHello
and SayBye
functions.
In the example below, the SayHello
function is 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:
$ ./wale
This 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 best from both worlds. This provides to a legacy system a modern language that can improve their maintainance costs and business needs. It maximize code reusability in the Go
ecosystem.
go share library的更多相关文章
- Different ways to invoke a shared object/share library(.so)
在Linux中调用.so文件的方法有几种. 1.直接在编译的时候链接上. 2.dlopen/???
- eclipse 启动报share library load faild
eclipse 与 jdk 版本要一致 *32 - 对应32位 *64 - 对应64位
- 浅析C/C++ library
1 背景 原来跑的好好的进程,重启后没跑多少就挂掉了,奇怪了.经过跟踪,原来是加载了一个.so文件,于是决定学习一下library相关的东东,现在和大家分享一下. 2 分类 C/C++ library ...
- 如何使用event 10049分析定位library cache lock and library cache pin
Oracle Library Cache 的 lock 与 pin 说明 一. 相关的基本概念 之前整理了一篇blog,讲了Library Cache 的机制,参考: Oracle Library c ...
- APP漏洞扫描用地址空间随机化
APP漏洞扫描用地址空间随机化 前言 我们在前文<APP漏洞扫描器之本地拒绝服务检测详解>了解到阿里聚安全漏洞扫描器有一项静态分析加动态模糊测试的方法来检测的功能,并详细的介绍了它在针对本 ...
- Linux文件与目录管理
. 代表此层目录 . . 代表上一层目录 - 代表前一个工作目录 ~ 代表"目前用户身份"所在的中文件夹 ~account 代表accoun ...
- Android NDK之JNI陷阱
背景: 最近一个月一直在做移植库的工作,将c代码到share library移植到Android平台.这就涉及到Android NDK(native develop kit)内容.这里只想记录下JNI ...
- 【原创】Capture CIS利用Access数据库建立封装库说明
1.在服务器端建立新空间,方便封装库以及数据库的归档存放 服务器路径:\\192.168.1.234\Share\STG_LIB,文件夹内容如下,其中Datesheet存放物料数据手册,Pcb_Lib ...
- MySQL CMake参数说明手册
MySQL自5.5版本以后,就开始使用CMake编译工具了,因此,你在安装源文件中找不到configure文件是正常的.很多人下到了新版的MySQL,因为找不到configure文件,不知道该怎么继续 ...
随机推荐
- hdu1015
#include <stdio.h>#include <string.h>#include <stdlib.h> int cmp(void* a, void* b) ...
- 《JS权威指南学习总结--7.10 数组类型》
内容要点: 一.数组类型 判断它是否为数组通常非常有用.在ES5中,可以使用Array.isArray()函数来做这件事情: Array.isArray([]); //=>true Array. ...
- javascript 拖放效果
最近一直在看javascript的书籍,有些东西在书上看着貌似理解了,但是在真正动手实践时,其实有些细节你根本不了解.所以看起来就算是一个简单的效果,写起来也未必简单,就算写起来简单,写的代码也未必规 ...
- OpenCV2.x自学笔记——自适应阈值
adaptiveThreshold(src,dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, do ...
- 朱丽叶—Cuda+OSG
#include <cuda_runtime.h> #include <osg/Image> ; typedef struct cuComplex { float r; flo ...
- Where is the python library installed?
configure: error: Could not link test program to Python. Maybe the main Python library has been inst ...
- Linux系统安装建议
1.推荐使用CentOS-6.x 64位版本:2.分区,推荐分出/usr/local用来存放应用程序./data分区用来存放数据,具体分区建议如下:/boot 100Mswap 4096M (视内存大 ...
- js中的随机数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- ThinkPHP框架基础
ThinkPHP 一.php框架基础介绍 真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维 ...
- lua: Learning Official Doc notes
dynamically typed vars: basic types: nil, boolean, number, string, function, userdata, thread & ...