1
0
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:
源文雨
2026-03-22 18:12:12 +08:00
parent e91efbc86f
commit 64f95b23a7
33 changed files with 9568 additions and 265 deletions

15
internal/zecall/errors.go Normal file
View 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")
)

View 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
}

View File

@@ -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

View 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
}

View File

@@ -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