github.com/golang/gofrontend@v0.0.0-20240429183944-60f985a78526/libgo/misc/cgo/test/issue4029.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !windows && !static && (!darwin || (!internal_pie && !arm64))
     6  // +build !windows
     7  // +build !static
     8  // +build !darwin !internal_pie,!arm64
     9  
    10  // Excluded in darwin internal linking PIE mode, as dynamic export is not
    11  // supported.
    12  // Excluded in internal linking mode on darwin/arm64, as it is always PIE.
    13  
    14  package cgotest
    15  
    16  /*
    17  #include <stdint.h>
    18  #include <dlfcn.h>
    19  #cgo linux LDFLAGS: -ldl
    20  
    21  extern uintptr_t dlopen4029(char*, int);
    22  extern uintptr_t dlsym4029(uintptr_t, char*);
    23  extern int dlclose4029(uintptr_t);
    24  
    25  extern void call4029(uintptr_t arg);
    26  */
    27  import "C"
    28  
    29  import (
    30  	"testing"
    31  )
    32  
    33  var callbacks int
    34  
    35  //export IMPIsOpaque
    36  func IMPIsOpaque() {
    37  	callbacks++
    38  }
    39  
    40  //export IMPInitWithFrame
    41  func IMPInitWithFrame() {
    42  	callbacks++
    43  }
    44  
    45  //export IMPDrawRect
    46  func IMPDrawRect() {
    47  	callbacks++
    48  }
    49  
    50  //export IMPWindowResize
    51  func IMPWindowResize() {
    52  	callbacks++
    53  }
    54  
    55  func test4029(t *testing.T) {
    56  	loadThySelf(t, "IMPWindowResize")
    57  	loadThySelf(t, "IMPDrawRect")
    58  	loadThySelf(t, "IMPInitWithFrame")
    59  	loadThySelf(t, "IMPIsOpaque")
    60  	if callbacks != 4 {
    61  		t.Errorf("got %d callbacks, expected 4", callbacks)
    62  	}
    63  }
    64  
    65  func loadThySelf(t *testing.T, symbol string) {
    66  	this_process := C.dlopen4029(nil, C.RTLD_NOW)
    67  	if this_process == 0 {
    68  		t.Error("dlopen:", C.GoString(C.dlerror()))
    69  		return
    70  	}
    71  	defer C.dlclose4029(this_process)
    72  
    73  	symbol_address := C.dlsym4029(this_process, C.CString(symbol))
    74  	if symbol_address == 0 {
    75  		t.Error("dlsym:", C.GoString(C.dlerror()))
    76  		return
    77  	}
    78  	t.Log(symbol, symbol_address)
    79  	C.call4029(symbol_address)
    80  }