Source file src/cmd/cgo/internal/test/issue4029.go

     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)
     6  
     7  // Excluded in darwin internal linking PIE (which is the default) mode,
     8  // as dynamic export is not supported.
     9  
    10  package cgotest
    11  
    12  /*
    13  #include <stdint.h>
    14  #include <stdlib.h>
    15  #include <dlfcn.h>
    16  #cgo linux LDFLAGS: -ldl
    17  
    18  extern uintptr_t dlopen4029(char*, int);
    19  extern uintptr_t dlsym4029(uintptr_t, char*);
    20  extern int dlclose4029(uintptr_t);
    21  
    22  extern void call4029(uintptr_t arg);
    23  */
    24  import "C"
    25  
    26  import (
    27  	"testing"
    28  	"unsafe"
    29  )
    30  
    31  var callbacks int
    32  
    33  //export IMPIsOpaque
    34  func IMPIsOpaque() {
    35  	callbacks++
    36  }
    37  
    38  //export IMPInitWithFrame
    39  func IMPInitWithFrame() {
    40  	callbacks++
    41  }
    42  
    43  //export IMPDrawRect
    44  func IMPDrawRect() {
    45  	callbacks++
    46  }
    47  
    48  //export IMPWindowResize
    49  func IMPWindowResize() {
    50  	callbacks++
    51  }
    52  
    53  func test4029(t *testing.T) {
    54  	loadThySelf(t, "IMPWindowResize")
    55  	loadThySelf(t, "IMPDrawRect")
    56  	loadThySelf(t, "IMPInitWithFrame")
    57  	loadThySelf(t, "IMPIsOpaque")
    58  	if callbacks != 4 {
    59  		t.Errorf("got %d callbacks, expected 4", callbacks)
    60  	}
    61  }
    62  
    63  func loadThySelf(t *testing.T, symbol string) {
    64  	this_process := C.dlopen4029(nil, C.RTLD_NOW)
    65  	if this_process == 0 {
    66  		t.Error("dlopen:", C.GoString(C.dlerror()))
    67  		return
    68  	}
    69  	defer C.dlclose4029(this_process)
    70  
    71  	symCStr := C.CString(symbol)
    72  	defer C.free(unsafe.Pointer(symCStr))
    73  	symbol_address := C.dlsym4029(this_process, symCStr)
    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  }
    81  

View as plain text