dlfcn_cgo_unix.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // SPDX-License-Identifier: Apache-2.0
  2. // SPDX-FileCopyrightText: 2024 The Ebitengine Authors
  3. //go:build freebsd || linux
  4. package cgo
  5. /*
  6. #cgo LDFLAGS: -ldl
  7. #include <dlfcn.h>
  8. #include <stdlib.h>
  9. */
  10. import "C"
  11. import (
  12. "errors"
  13. "unsafe"
  14. )
  15. func Dlopen(filename string, flag int) (uintptr, error) {
  16. cfilename := C.CString(filename)
  17. defer C.free(unsafe.Pointer(cfilename))
  18. handle := C.dlopen(cfilename, C.int(flag))
  19. if handle == nil {
  20. return 0, errors.New(C.GoString(C.dlerror()))
  21. }
  22. return uintptr(handle), nil
  23. }
  24. func Dlsym(handle uintptr, symbol string) (uintptr, error) {
  25. csymbol := C.CString(symbol)
  26. defer C.free(unsafe.Pointer(csymbol))
  27. symbolAddr := C.dlsym(*(*unsafe.Pointer)(unsafe.Pointer(&handle)), csymbol)
  28. if symbolAddr == nil {
  29. return 0, errors.New(C.GoString(C.dlerror()))
  30. }
  31. return uintptr(symbolAddr), nil
  32. }
  33. func Dlclose(handle uintptr) error {
  34. result := C.dlclose(*(*unsafe.Pointer)(unsafe.Pointer(&handle)))
  35. if result != 0 {
  36. return errors.New(C.GoString(C.dlerror()))
  37. }
  38. return nil
  39. }
  40. // all that is needed is to assign each dl function because then its
  41. // symbol will then be made available to the linker and linked to inside dlfcn.go
  42. var (
  43. _ = C.dlopen
  44. _ = C.dlsym
  45. _ = C.dlerror
  46. _ = C.dlclose
  47. )