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文件,不知道该怎么继续 ...
随机推荐
- linux jdk环境变量
export JAVA_HOME=/usr/share/jdk8 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/ ...
- 第九十三节,html5+css3移动手机端流体布局,基础CSS,头部设计,轮播设计,底部设计
html5+css3移动手机端流体布局,基础CSS,头部设计,轮播设计,底部设计 基础CSS 首先将通用css属性写好 @charset "utf-8"; /*通用样式*/ /*去 ...
- iOS开发加快审核app
实现app加快审核的步骤: 1.https://developer.apple.com/contact/进入这个网址点击App Store下的Expediting an App Review进入这个页 ...
- Sass与Compress实战:第四章
概要:这一章将深挖Compass的工具箱,看看Compass的混合器如何帮助你省去编写重复样式表的辛苦工作. 本章内容: ● 使用Compass重置浏览器默认样式表 ● 改进样式表排版的Compass ...
- 【转发】彻底理解 JS 中 this 的指向
为什么要学习this?如果你学过函数式编程,面向对象编程,那你肯定知道干什么用的,如果你没有学过,那么暂时可以不用看这篇文章,当然如果你有兴趣也可以看看,毕竟这是js中必须要掌握的东西. 例子1: f ...
- JavaEE JavaBean 反射、内省、BeanUtils
JavaEE JavaBean 反射.内省.BeanUtils @author ixenos JavaBean是什么 一种规范,表达实体和信息的规范,便于封装重用. 1.所有属性为private2.提 ...
- 【转】动态字节码技术跟踪Java程序
Whats is Java Agent? .. java.lang.instrument.Instrumentation 之前有写 基于AOP的日志调试 讨论一种跟踪Java程序的方法, 但不是很 ...
- 有关下行HARQ的一切
1. 对于下行HARQ,有几种类型的下行传输需要UE反馈ACK/NACK 动态调度的下行传输:UE收到一个使用C-RNTI或TC-RNTI(对应随机接入过程中的Msg4)加扰的PDCCH和PDSCH, ...
- hdu 1859 最小长方形
Description 给定一系列2维平面点的坐标(x, y),其中x和y均为整数,要求用一个最小的长方形框将所有点框在内.长方形框的边分别平行于x和y坐标轴,点落在边上也算是被框在内. Input ...
- Xcode8中添加SnapKit框架报错,编译失败
既然SnapKit的作者说SnapKit已经支持Swift3.0了,那么我们就先来适配SnapKit,首先用Xcode8新建一个空项目,利用Cocoapods导入SnapKit. Podfile 打 ...