David Chou
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}
package print
// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"
func Print(s string) {
cs := C.CString(s)
C.fputs(cs, (*C.FILE)(C.stdout))
C.free(unsafe.Pointer(cs))
}package calc
import "fmt"
func SayHello(name string) {
fmt.Printf("Go says: Hello, %s!\n", name)
}
func Add(num0, num1 int) int {
return num0 + num1
}package main
import (
"fmt"
"github.com/david7482/go-plugin-playground/calc"
)
func main() {
fmt.Print("This is a Go Application.\n")
calc.SayHello("World")
fmt.Printf("Add(3, 5): %d\n", calc.Add(3, 5))
}# go build main.go
# ./main
This is a Go Application.
Go says: Hello, World!
Add(3, 5): 8
# ls main -lh
-rwxr-xr-x 1 root root 1.5M Feb 15 17:25 main# go install -buildmode=shared std
# go install -buildmode=shared -linkshared github.com/david7482/go-plugin/calc
# go build -buildmode=shared -linkshared main.go
# ls -lh main
-rwxr-xr-x 1 root root 20K Feb 15 17:43 main# ldd main
linux-vdso.so.1
libstd.so => ${GOROOT}/pkg/linux_amd64_dynlink/libstd.so
libgithub.com-david7482-go-plugin-calc.so =>
${GOPATH}/pkg/linux_amd64_dynlink/libgithub.com-david7482-go-plugin-calc.so
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
/lib64/ld-linux-x86-64.so.2
# ls -gGh ${GOROOT}/pkg/linux_amd64_dynlink/libstd.so
-rw-r--r-- 1 38M Feb 15 11:49 /usr/local/go/pkg/linux_amd64_dynlink/libstd.so
# ls -gGh ${GOPATH}/pkg/linux_amd64_dynlink/libgithub.com-david7482-go-plugin-calc.so
-rw-r--r-- 1 21K Feb 15 17:39 /go/pkg/linux_amd64_dynlink/libgithub.com-david7482-go-plugin-calc.sopackage main
import "C"
func main() {}
//export SayHello
func SayHello(name string) {
fmt.Printf("Go says: Hello, %s!\n", name)
}
//export Add
func Add(num0, num1 int) int {
return num0 + num1
}# go build -buildmode=c-shared -o calc.so calc.go
# go build -buildmode=c-archive -o calc.a calc.go
# ls calc.*
calc.a calc.so calc.h#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
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 float _Complex GoComplex64;
typedef double _Complex GoComplex128;
typedef struct { const 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
#ifdef __cplusplus
extern "C" {
#endif
extern void SayHello(GoString p0);
extern GoInt Add(GoInt p0, GoInt p1);
#ifdef __cplusplus
}
#endif#include "calc.h"
#include <stdio.h>
#include <string.h>
int main() {
printf("This is a C Application.\n");
GoString name;
name.p = "World";
name.n = strlen(name.p);
SayHello(name);
printf("Add(3, 5): %d\n", Add(3, 5));
return 0;
}# gcc -o main main.cpp calc.a -lpthread
# gcc -o main main.cpp calc.so -lpthread
# ./main
This is a C Application.
Go says: Hello, World!
Add(3, 5): 8
# readelf -d main | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [calc.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
# readelf -d calc.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]package main
import "C"
func SayHello(name string) {
fmt.Printf("Go says: Hello, %s!\n", name)
}
func Add(num0, num1 int) int {
return num0 + num1
}# go build -buildmode=plugin -o calc.so calc.go
# ls calc.*
calc.go calc.sopackage main
import (
"fmt"
"plugin"
)
func main() {
fmt.Println("This is a Go Application");
p, err := plugin.Open("calc.so")
if err != nil {
panic(err)
}
sayHelloSymbol, err := p.Lookup("SayHello")
if err != nil {
panic(err)
}
addSymbol, err := p.Lookup("Add")
if err != nil {
panic(err)
}
sayHelloSymbol.(func(string))("World")
fmt.Printf("Add(3, 5): %d\n", addSymbol.(func(int, int)int)(3, 5))
}# go build main.go
# ./main
This is a Go Application
Go says: Hello, World!
Add(3, 5): 8
# readelf -d main | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]