Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin: what symbols are exported? #17823

Closed
wendigo opened this issue Nov 6, 2016 · 4 comments
Closed

plugin: what symbols are exported? #17823

wendigo opened this issue Nov 6, 2016 · 4 comments

Comments

@wendigo
Copy link

wendigo commented Nov 6, 2016

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version devel +2b445c7 Sat Nov 5 23:59:04 2016 +0000 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mateusz.gajewski/Desktop/Projects/"
GORACE=""
GOROOT="/usr/local/Cellar/go/HEAD-2b445c7/libexec"
GOTOOLDIR="/usr/local/Cellar/go/HEAD-2b445c7/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/43/1y0rrqr55zq3f8cj5wpkt1kmhc7r33/T/go-build808603188=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

plugin.go:

package main

type TypeA func(int) StructA

type StructA struct {
	Message string
}

func FuncA() StructA {
	return StructA{"Hello!"}
}

var VarA int32 = 32
var VarB StructA = StructA{"Hello!"}

const ConstA int32 = 64

host.go:

package main

import (
	"fmt"
	"plugin"
	"reflect"
	"unsafe"
)

type Plug struct {
	Path    string
	_       chan struct{}
	Symbols map[string]interface{}
}

func main() {
	p, err := plugin.Open("plugin.so")
	if err != nil {
		panic(err)
	}

	inspectPlugin(p)
}

func inspectPlugin(p *plugin.Plugin) {
	pl := (*Plug)(unsafe.Pointer(p))

	fmt.Printf("Plugin %s exported symbols (%d): \n", pl.Path, len(pl.Symbols))

	for name, pointers := range pl.Symbols {
		fmt.Printf("symbol: %s, pointer: %v, type: %v\n", name, pointers, reflect.TypeOf(pointers))
	}
}

What did you expect to see?

I would expect that all public symbols are exported (all defined types, functions, vars and constants).

What did you see instead?

Instead I can see:

Plugin command-line-arguments exported symbols (3):
symbol: FuncA, pointer: 0x5841800, type: func() main.StructA
symbol: VarA, pointer: 0x58813e4, type: *int32
symbol: VarB, pointer: &{Hello!}, type: *main.StructA
@wendigo
Copy link
Author

wendigo commented Nov 6, 2016

Also there's no possibility to call FuncA: panic: interface conversion: plugin.Symbol is func() main.StructA, not func() main.StructA

@ianlancetaylor
Copy link
Contributor

I think the docs are clear: "A symbol is any exported variable or function."

@wendigo
Copy link
Author

wendigo commented Nov 6, 2016

How to call then a function returning a struct?

@josharian josharian changed the title plugins: what symbols are exported? plugin: what symbols are exported? Nov 7, 2016
@crawshaw
Copy link
Member

crawshaw commented Nov 7, 2016

You can extract the struct type from the function:

fn := ...
outType := reflect.ValueOf(fn).Type().Out(0)

Whether or not the plugin package listed exported types among symbols, if you don't have the type statically imported into the host, you are stuck using reflection to work with it. The effort of extracting the return type from a function is small compared to what will be necessary to work with it via reflection.

@crawshaw crawshaw closed this as completed Nov 7, 2016
@golang golang locked and limited conversation to collaborators Nov 7, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants