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