mirror of
https://github.com/fumiama/gozel.git
synced 2026-06-20 09:30:26 +08:00
feat(gen&zecall): add function support
This commit is contained in:
15
internal/zecall/errors.go
Normal file
15
internal/zecall/errors.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package zecall
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotImplemented is a stub error.
|
||||
ErrNotImplemented = errors.New("zecall is not implemtent on" + runtime.GOOS + " " + runtime.GOARCH)
|
||||
// ErrZeCallNotInit please call Init() first.
|
||||
ErrZeCallNotInit = errors.New("zecall not init")
|
||||
// ErrNoSuchProcess please register the process first.
|
||||
ErrNoSuchProcess = errors.New("no such process")
|
||||
)
|
||||
38
internal/zecall/generic.go
Normal file
38
internal/zecall/generic.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package zecall
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type ReturnTypes interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 |
|
||||
~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
||||
}
|
||||
|
||||
// Call invokes a registered proc by name. For generated call only.
|
||||
// The go:uintptrescapes directive tells the compiler that args may contain
|
||||
// pointers converted to uintptr, so the GC will keep them alive during the call.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func Call[T ReturnTypes](name string, args ...uintptr) (r T, err error) {
|
||||
r1, r2, err := Syscall(name, args...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
k := reflect.TypeOf(r).Kind()
|
||||
switch k {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16,
|
||||
reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8,
|
||||
reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
r = (T)(r1)
|
||||
case reflect.Float32:
|
||||
r = (T)(math.Float32frombits(uint32(r2)))
|
||||
case reflect.Float64:
|
||||
r = (T)(math.Float64frombits(uint64(r2)))
|
||||
default:
|
||||
err = errors.New("zecall unsupported kind " + k.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package zecall
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
@@ -11,13 +10,6 @@ const (
|
||||
zeLibraryName = "libze_loader.so"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrZeCallNotInit please call Init() first.
|
||||
ErrZeCallNotInit = errors.New("zecall not init")
|
||||
// ErrNoSuchProcess please register the process first.
|
||||
ErrNoSuchProcess = errors.New("no such process")
|
||||
)
|
||||
|
||||
var (
|
||||
libZeLoader uintptr
|
||||
procMap = map[string]uintptr{}
|
||||
@@ -47,12 +39,12 @@ func Register(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Call invokes a registered proc by name. For generated call only.
|
||||
// Syscall invokes a registered proc by name. For generated call only.
|
||||
// The go:uintptrescapes directive tells the compiler that args may contain
|
||||
// pointers converted to uintptr, so the GC will keep them alive during the call.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func Call(name string, args ...uintptr) (r1, r2 uintptr, err error) {
|
||||
func Syscall(name string, args ...uintptr) (r1, r2 uintptr, err error) {
|
||||
fn, ok := procMap[name]
|
||||
if !ok {
|
||||
return 0, 0, ErrNoSuchProcess
|
||||
|
||||
15
internal/zecall/zecall_stub.go
Normal file
15
internal/zecall/zecall_stub.go
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build !linux && !windows
|
||||
|
||||
package zecall
|
||||
|
||||
// Register a process for calling. For generated init only. Not thread-safe.
|
||||
func Register(string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
// Syscall invokes a registered proc by name. For generated call only.
|
||||
// The go:uintptrescapes directive tells the compiler that args may contain
|
||||
// pointers converted to uintptr, so the GC will keep them alive during the call.
|
||||
func Syscall(name string, args ...uintptr) (uintptr, uintptr, error) {
|
||||
return 0, 0, ErrNotImplemented
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package zecall
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
@@ -9,13 +8,6 @@ const (
|
||||
zeLibraryName = "ze_loader.dll"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrZeCallNotInit please call Init() first.
|
||||
ErrZeCallNotInit = errors.New("zecall not init")
|
||||
// ErrNoSuchProcess please register the process first.
|
||||
ErrNoSuchProcess = errors.New("no such process")
|
||||
)
|
||||
|
||||
var (
|
||||
libZeLoader *syscall.DLL
|
||||
procMap = map[string]*syscall.Proc{}
|
||||
@@ -45,12 +37,12 @@ func Register(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Call invokes a registered proc by name. For generated call only.
|
||||
// Syscall invokes a registered proc by name. For generated call only.
|
||||
// The go:uintptrescapes directive tells the compiler that args may contain
|
||||
// pointers converted to uintptr, so the GC will keep them alive during the call.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func Call(name string, args ...uintptr) (r1, r2 uintptr, err error) {
|
||||
func Syscall(name string, args ...uintptr) (r1, r2 uintptr, err error) {
|
||||
fn, ok := procMap[name]
|
||||
if !ok {
|
||||
return 0, 0, ErrNoSuchProcess
|
||||
|
||||
Reference in New Issue
Block a user