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

如果我想要调用的函数参数个数和类型不定,应该如何使用? #50

Closed
honey-yogurt opened this issue Apr 23, 2022 · 4 comments
Labels
question Further information is requested

Comments

@honey-yogurt
Copy link

image

image

如果这个Hello函数参数个数以及类型不定,应该如何使用goloader?

@pkujhd pkujhd added the question Further information is requested label Apr 24, 2022
@pkujhd
Copy link
Owner

pkujhd commented Apr 24, 2022

不行,必须知晓函数签名

@pkujhd pkujhd closed this as completed Apr 24, 2022
@eh-steve
Copy link

eh-steve commented Nov 5, 2022

The JIT compiler in #66 will return the function symbols as a map[string]interface{} which you can either type switch/type assert on or use reflection to find out the number and types of function in/out args.

You can simply do:

loadable, err = jit.BuildGoFiles(jit.BuildConfig{}, "./path/to/file1.go", "/path/to/file2.go")
// or
loadable, err = jit.BuildGoPackage(jit.BuildConfig{}, "./path/to/package")
// or
loadable, err = jit.BuildGoText(jit.BuildConfig{}, `
package mypackage

import "encoding/json"


func MyFunc(input []byte) (interface{}, error) {
	var output interface{}
	err := json.Unmarshal(input, &output)
	return output, err
}

`)

if err != nil {
    panic(err)
}

module, symbols, err = loadable.Load()

if err != nil {
    panic(err)
}

MyFunc := symbols["MyFunc"].(func([]byte) (interface{}, error))

@pkujhd
Copy link
Owner

pkujhd commented Nov 7, 2022

@eh-steve “.(func([]byte) (interface{}, error)” means you already know function type.

@eh-steve
Copy link

eh-steve commented Nov 7, 2022

(Or you can type switch across multiple different function types, or use reflect to check the in/out args and then call it programmatically):

switch MyFunc := symbols["MyFunc"].(type) {
case func([]byte) (interface{}, error):
    out, err := MyFunc([]byte(`{"a": "b"}`))
case func(in1 []byte, in2 int) (map[string]interface{}, error):
    out, err := MyFunc([]byte(`{"a": "b"}`), 5)
}

or:

v := reflect.ValueOf(symbols["MyFunc"])
t := v.Type()

inputs := t.NumIn()
outputs := t.NumOut()
argv := make([]reflect.Value, inputs)
for i := 0; i < inputs; i++ {
    in := t.In(i)
    // check the type of `in` and decide where to get the value from/do any type conversion as required
    argv[i] = reflect.ValueOf(someInput)
}
results := v.Call(argv)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants