티스토리 뷰

Technology/Golang

Go plugin ? C library in Go ?

캡틴테크 2017. 6. 1. 01:14
반응형

Today, I would like to indicate how to use library in Go.

There are few types of libraries. Basically, library consists of two types like static library and shared library. I do not explain all of the types what it is. Just think about what library you have to choose. Assuming my project is based on go files and run on independent container which is required libraries in order to run an executable file.  Once I give it a shot to make 2 types of library. One is  shared library based on Go file. The other is static library based on C file. 

# plugin, newly add up to go compiler !

From 1.8 of Go compiler we can use plugin native package(https://golang.org/pkg/plugin/) which is plugin implements loading and symbol resolution of go plugins. The way of creating so file is extremely simple.

package main

import "fmt"

func Helloworld(){
	fmt.Println("Hello World!!")
}

func Add(a, b int)(int) {
	return a + b
}

The code of Go is hello.go and provides Helloworld() and Add() methods. You have to capital letter for first letter of function. If you don't use capital letter, it will not be found out in main code.

If you done to make the code and try to build with the command.

go build -buildmode=plugin -o helloplugin.so hello.go

Right after the build, you can see helloplugin.so in the same level.

package main

import "fmt"
import "plugin"

func main() {
  	fmt.Println("StartMain")

  	p, err := plugin.Open("./lib/helloplugin.so")
	if err != nil {
		panic(err)
	}

	f, err := p.Lookup("Helloworld")
	if err != nil {
		panic(err)
	}

	f.(func())()

	f1, err := p.Lookup("Add")
	if err != nil {
		panic(err)
	}

	sum := f1.(func(int, int) int)(1, 2)

	fmt.Println(sum)
}

This is main.go file to check plugin functionality. Using 'plugin' native package, you can include own shared library and find function using function strings. I had tested with 'Helloworld' and 'Add' strings to call and call it with parameters. If you test it, you can see appropriate answer.

# C library, we can use it in Go

Many of C library I made it before and no time to covert to go project. In case of this circumstance, we can use static library of C and call it thanks to 'CGO'

cal.c file
#include "cal.h"

int add(int a, int b)
{
	return a+b;
}
cal.h file
int add(int a, int b);

You can make .a library with the c/h file.

gcc -O2 -c cal.c
ar q libcal.a cal.o

If you done to build with gcc, you can find out libcal.a and cal.o. Movie libcal.a to lib folder.

package main

import "fmt"
import "plugin"

// #cgo CFLAGS: -I.
// #cgo LDFLAGS: -L. ./lib/libcal.a
// #include "./include/cal.h"
import "C"

func main() {
  	fmt.Println("StartMain")
  	fmt.Println("C library ", C.add(10,20) )

  	p, err := plugin.Open("./lib/helloplugin.so")
	if err != nil {
		panic(err)
	}

	f, err := p.Lookup("Helloworld")
	if err != nil {
		panic(err)
	}

	f.(func())()

	f1, err := p.Lookup("Add")
	if err != nil {
		panic(err)
	}

	sum := f1.(func(int, int) int)(1, 2)

	fmt.Println(sum)
}

 The code is finaly main.go file with two types of libraries. If you want to use '.a' library based on C. Use 'Import "C"' and define cgo build options like CFLAGS and LDFLAGS. Just ahead of 'Import "C"' you have to write the define in order to build properly. Even though shared library of C is there, we can build it with CGO build option. Please utilize the example to make promoted project.

# Sample Code

git clone https://github.com/Namsulee/go-sample.git

반응형
댓글