dlfcn_cgo_unix.go raw

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