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