annotate go/godc/godc.go @ 35:75fe1dec0eb4

- added support for signature-based calling convention switch
author Tassilo Philipp
date Mon, 13 Apr 2020 16:07:56 +0200
parents 8a45a05ff64e
children 1e3d929e43be
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 godc.go
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Copyright (c) 2014 Tassilo Philipp <tphilipp@potion-studios.com>
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Permission to use, copy, modify, and distribute this software for any
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 purpose with or without fee is hereby granted, provided that the above
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8 copyright notice and this permission notice appear in all copies.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 */
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 // Go/dyncall extension implementation.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 package godc
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
9
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
24 // #cgo LDFLAGS: -ldyncall_s
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
25 // #cgo LDFLAGS: -ldynload_s
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
26 // #cgo LDFLAGS: -ldyncallback_s
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 // #include <stdlib.h>
9
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
28 // #include "dyncall.h"
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
29 // #include "dynload.h"
8a45a05ff64e - go binding cleanup, not enforcing relative paths anymore, readme update
cslag
parents: 0
diff changeset
30 // #include "dyncall_signature.h"
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 import "C"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 import (
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 "unsafe"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 "fmt"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 "reflect"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 type ExtLib struct {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 lib *C.DLLib
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 syms *C.DLSyms
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 type CallVM struct {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 cvm *C.DCCallVM
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 // dynload
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 func (p *ExtLib) Load(path string) error {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 s := C.CString(path)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 defer C.free(unsafe.Pointer(s))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 p.lib = C.dlLoadLibrary(s)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 if p.lib != nil { return nil }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 return fmt.Errorf("Can't load %s", path)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 func (p *ExtLib) Free() {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 C.dlFreeLibrary(p.lib)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 func (p *ExtLib) FindSymbol(name string) unsafe.Pointer {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 s := C.CString(name)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 defer C.free(unsafe.Pointer(s))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 return unsafe.Pointer(C.dlFindSymbol(p.lib, s))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 // dynload Syms
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 func (p *ExtLib) SymsInit(path string) error {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 s := C.CString(path)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 defer C.free(unsafe.Pointer(s))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 p.syms = C.dlSymsInit(s)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 if p.syms != nil { return nil }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 return fmt.Errorf("Can't load %s", path)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 func (p *ExtLib) SymsCleanup() {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 C.dlSymsCleanup(p.syms)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 func (p *ExtLib) SymsCount() int {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 return int(C.dlSymsCount(p.syms))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 func (p *ExtLib) SymsName(i int) string {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 return C.GoString(C.dlSymsName(p.syms, C.int(i)))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 func (p *ExtLib) SymsNameFromValue(v unsafe.Pointer) string {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 return C.GoString(C.dlSymsNameFromValue(p.syms, v))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 // dyncall
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95 func (p *CallVM) InitCallVM() error {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 return p.InitCallVMWithStackSize(4096)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99 func (p *CallVM) InitCallVMWithStackSize(stackSize int) error {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 p.cvm = C.dcNewCallVM(C.DCsize(stackSize))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101 if p.cvm != nil { return nil }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 return fmt.Errorf("Can't create CallVM")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 func (p *CallVM) Free() {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 C.dcFree(p.cvm)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 func (p *CallVM) Reset() {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 C.dcReset(p.cvm)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 // Modes
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 const (
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 DC_CALL_C_DEFAULT = C.DC_CALL_C_DEFAULT
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 DC_CALL_C_ELLIPSIS = C.DC_CALL_C_ELLIPSIS
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 DC_CALL_C_ELLIPSIS_VARARGS = C.DC_CALL_C_ELLIPSIS_VARARGS
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 DC_CALL_C_X86_CDECL = C.DC_CALL_C_X86_CDECL
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 DC_CALL_C_X86_WIN32_STD = C.DC_CALL_C_X86_WIN32_STD
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 DC_CALL_C_X86_WIN32_FAST_MS = C.DC_CALL_C_X86_WIN32_FAST_MS
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 DC_CALL_C_X86_WIN32_FAST_GNU = C.DC_CALL_C_X86_WIN32_FAST_GNU
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 DC_CALL_C_X86_WIN32_THIS_MS = C.DC_CALL_C_X86_WIN32_THIS_MS
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 DC_CALL_C_X86_WIN32_THIS_GNU = C.DC_CALL_C_X86_WIN32_THIS_GNU
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 DC_CALL_C_X64_WIN64 = C.DC_CALL_C_X64_WIN64
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 DC_CALL_C_X64_SYSV = C.DC_CALL_C_X64_SYSV
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 DC_CALL_C_PPC32_DARWIN = C.DC_CALL_C_PPC32_DARWIN
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129 DC_CALL_C_PPC32_OSX = C.DC_CALL_C_PPC32_OSX
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 DC_CALL_C_ARM_ARM_EABI = C.DC_CALL_C_ARM_ARM_EABI
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 DC_CALL_C_ARM_THUMB_EABI = C.DC_CALL_C_ARM_THUMB_EABI
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 DC_CALL_C_ARM_ARMHF = C.DC_CALL_C_ARM_ARMHF
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 DC_CALL_C_MIPS32_EABI = C.DC_CALL_C_MIPS32_EABI
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134 DC_CALL_C_MIPS32_PSPSDK = C.DC_CALL_C_MIPS32_PSPSDK
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 DC_CALL_C_PPC32_SYSV = C.DC_CALL_C_PPC32_SYSV
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 DC_CALL_C_PPC32_LINUX = C.DC_CALL_C_PPC32_LINUX
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 DC_CALL_C_ARM_ARM = C.DC_CALL_C_ARM_ARM
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 DC_CALL_C_ARM_THUMB = C.DC_CALL_C_ARM_THUMB
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 DC_CALL_C_MIPS32_O32 = C.DC_CALL_C_MIPS32_O32
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 DC_CALL_C_MIPS64_N32 = C.DC_CALL_C_MIPS64_N32
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 DC_CALL_C_MIPS64_N64 = C.DC_CALL_C_MIPS64_N64
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 DC_CALL_C_X86_PLAN9 = C.DC_CALL_C_X86_PLAN9
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 DC_CALL_C_SPARC32 = C.DC_CALL_C_SPARC32
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 DC_CALL_C_SPARC64 = C.DC_CALL_C_SPARC64
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 DC_CALL_SYS_DEFAULT = C.DC_CALL_SYS_DEFAULT
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 DC_CALL_SYS_X86_INT80H_LINUX = C.DC_CALL_SYS_X86_INT80H_LINUX
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 DC_CALL_SYS_X86_INT80H_BSD = C.DC_CALL_SYS_X86_INT80H_BSD
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 func (p *CallVM) Mode(mode int) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 C.dcMode(p.cvm, C.DCint(mode))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 // Error codes
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 const (
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157 DC_ERROR_NONE = C.DC_ERROR_NONE
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158 DC_ERROR_UNSUPPORTED_MODE = C.DC_ERROR_UNSUPPORTED_MODE
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 func (p *CallVM) GetError() int {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 return int(C.dcGetError(p.cvm))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 // Helper for string/pointer conversion, needed as low-level string alloc needs to be freed in different scope
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 func (p *CallVM) AllocCString(value string) unsafe.Pointer { s := C.CString(value); return unsafe.Pointer(s) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169 func (p *CallVM) FreeCString (value unsafe.Pointer) { C.free(value) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171 // Args
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 func (p *CallVM) ArgBool (value bool) { if value==true { C.dcArgBool(p.cvm, C.DC_TRUE) } else { C.dcArgBool(p.cvm, C.DC_FALSE) } }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 func (p *CallVM) ArgChar (value int8) { C.dcArgChar (p.cvm, C.DCchar (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 func (p *CallVM) ArgShort (value int16) { C.dcArgShort (p.cvm, C.DCshort (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 func (p *CallVM) ArgInt (value int) { C.dcArgInt (p.cvm, C.DCint (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 func (p *CallVM) ArgLong (value int32) { C.dcArgLong (p.cvm, C.DClong (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 func (p *CallVM) ArgLongLong (value int64) { C.dcArgLongLong(p.cvm, C.DClonglong(value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178 func (p *CallVM) ArgFloat (value float32) { C.dcArgFloat (p.cvm, C.DCfloat (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 func (p *CallVM) ArgDouble (value float64) { C.dcArgDouble (p.cvm, C.DCdouble (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 func (p *CallVM) ArgPointer (value unsafe.Pointer) { C.dcArgPointer (p.cvm, C.DCpointer (value)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 //@@@func (p *CallVM) ArgStruct (s C.DCstruct*, value unsafe.Pointer)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183 // "Formatted" args
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184 // - first takes Go's types (as they cover all C types dyncall supports) and pushes values accordingly
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185 // - second uses a dyncall signature for implicit type conversion/casting, however it uses reflect package and is slower
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 // Note that first version doesn't feature calling convention mode switching.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 func (p *CallVM) ArgF_Go(args ...interface{}) error {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 for i, n := 0, len(args); i<n; i++ {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190 switch args[i].(type) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
191 case bool: p.ArgBool ( (args[i].(bool )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
192 case int8: p.ArgChar ( (args[i].(int8 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
193 case uint8/*byte*/: p.ArgChar (int8 (args[i].(uint8 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
194 case int16: p.ArgShort ( (args[i].(int16 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
195 case uint16: p.ArgShort (int16 (args[i].(uint16 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
196 case int: p.ArgInt ( (args[i].(int )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
197 case uint: p.ArgInt (int (args[i].(uint )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
198 case int32/*rune*/: p.ArgLong ( (args[i].(int32 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
199 case uint32: p.ArgLong (int32 (args[i].(uint32 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
200 case int64: p.ArgLongLong( (args[i].(int64 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
201 case uint64: p.ArgLongLong(int64 (args[i].(uint64 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
202 case float32: p.ArgFloat ( (args[i].(float32 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
203 case float64: p.ArgDouble ( (args[i].(float64 )))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
204 case uintptr: p.ArgPointer (unsafe.Pointer(args[i].(unsafe.Pointer)))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
205 case unsafe.Pointer: p.ArgPointer ( (args[i].(unsafe.Pointer)))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
206 default: return fmt.Errorf("Unknown type passed to ArgF_Go")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
207 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
208 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
209 return nil
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
210 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
211
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
212 func (p *CallVM) ArgF(signature string, args ...interface{}) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
213
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
214 tb := reflect.TypeOf((*bool )(nil)).Elem()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
215 ti := reflect.TypeOf((*int64 )(nil)).Elem()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
216 tf := reflect.TypeOf((*float64)(nil)).Elem()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
217 tp := reflect.TypeOf((*uintptr)(nil)).Elem()
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
218
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
219 for i, n := 0, len(signature); i<n; i++ {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
220 //@@@ add support for calling convention mode(s)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
221 switch s := signature[i]; s {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
222 case C.DC_SIGCHAR_BOOL: p.ArgBool (bool (reflect.ValueOf(args[i]).Convert(tb).Bool ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
223 case C.DC_SIGCHAR_CHAR, C.DC_SIGCHAR_UCHAR: p.ArgChar (int8 (reflect.ValueOf(args[i]).Convert(ti).Int ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
224 case C.DC_SIGCHAR_INT, C.DC_SIGCHAR_UINT: p.ArgInt (int (reflect.ValueOf(args[i]).Convert(ti).Int ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
225 case C.DC_SIGCHAR_LONG, C.DC_SIGCHAR_ULONG: p.ArgLong (int32 (reflect.ValueOf(args[i]).Convert(ti).Int ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
226 case C.DC_SIGCHAR_LONGLONG, C.DC_SIGCHAR_ULONGLONG: p.ArgLongLong(int64 (reflect.ValueOf(args[i]).Convert(ti).Int ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
227 case C.DC_SIGCHAR_FLOAT: p.ArgFloat (float32 (reflect.ValueOf(args[i]).Convert(tf).Float ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
228 case C.DC_SIGCHAR_DOUBLE: p.ArgDouble (float64 (reflect.ValueOf(args[i]).Convert(tf).Float ()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
229 case C.DC_SIGCHAR_POINTER, C.DC_SIGCHAR_STRING: p.ArgPointer (unsafe.Pointer(reflect.ValueOf(args[i]).Convert(tp).Pointer()))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
230 case C.DC_SIGCHAR_ENDARG: return
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
231 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
232 // Faster, but doesn't do cross-type conversions.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
233 //switch s := signature[i]; s {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
234 // case C.DC_SIGCHAR_BOOL: p.ArgBool (args[i].(bool ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
235 // case C.DC_SIGCHAR_CHAR, C.DC_SIGCHAR_UCHAR: p.ArgChar (args[i].(int8 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
236 // case C.DC_SIGCHAR_SHORT, C.DC_SIGCHAR_USHORT: p.ArgShort (args[i].(int16 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
237 // case C.DC_SIGCHAR_INT, C.DC_SIGCHAR_UINT: p.ArgInt (args[i].(int ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
238 // case C.DC_SIGCHAR_LONG, C.DC_SIGCHAR_ULONG: p.ArgLong (args[i].(int32 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
239 // case C.DC_SIGCHAR_LONGLONG, C.DC_SIGCHAR_ULONGLONG: p.ArgLongLong(args[i].(int64 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
240 // case C.DC_SIGCHAR_FLOAT: p.ArgFloat (args[i].(float32 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
241 // case C.DC_SIGCHAR_DOUBLE: p.ArgDouble (args[i].(float64 ))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
242 // case C.DC_SIGCHAR_POINTER, C.DC_SIGCHAR_STRING: p.ArgPointer (args[i].(unsafe.Pointer))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243 // case C.DC_SIGCHAR_ENDARG: return
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
244 //}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
245 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
246 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
247
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
248
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
249 // Calls
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
250 func (p *CallVM) CallVoid (funcptr unsafe.Pointer) { C.dcCallVoid (p.cvm, C.DCpointer(funcptr)) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
251 func (p *CallVM) CallBool (funcptr unsafe.Pointer) bool { b := (C.dcCallBool(p.cvm, C.DCpointer(funcptr))); if b==C.DC_TRUE { return true } else { return false } }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
252 func (p *CallVM) CallChar (funcptr unsafe.Pointer) int8 { return int8 (C.dcCallChar (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
253 func (p *CallVM) CallShort (funcptr unsafe.Pointer) int16 { return int16 (C.dcCallShort (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
254 func (p *CallVM) CallInt (funcptr unsafe.Pointer) int { return int (C.dcCallInt (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
255 func (p *CallVM) CallLong (funcptr unsafe.Pointer) int32 { return int32 (C.dcCallLong (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
256 func (p *CallVM) CallLongLong (funcptr unsafe.Pointer) int64 { return int64 (C.dcCallLongLong(p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
257 func (p *CallVM) CallFloat (funcptr unsafe.Pointer) float32 { return float32 (C.dcCallFloat (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
258 func (p *CallVM) CallDouble (funcptr unsafe.Pointer) float64 { return float64 (C.dcCallDouble (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
259 func (p *CallVM) CallPointer (funcptr unsafe.Pointer) unsafe.Pointer { return unsafe.Pointer(C.dcCallPointer (p.cvm, C.DCpointer(funcptr))) }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
260 func (p *CallVM) CallPointerToStr(funcptr unsafe.Pointer) string { return C.GoString((*C.char)(C.dcCallPointer (p.cvm, C.DCpointer(funcptr)))) } // For convenience
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
261 //@@@func (p *CallVM) CallStruct (funcptr unsafe.Pointer, s C.DCstruct* s, returnValue unsafe.Pointer)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
262
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
263 // "Formatted" calls
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
264 //@@@func (p *CallVM) Call(result, funcptr unsafe.Pointer, signature string, args ...interface{}) {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
265 //@@@...
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
266 //@@@}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
267
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
268
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
269 //void dcCallF (DCCallVM* vm, DCValue* result, DCpointer funcptr, const DCsigchar* signature, ...);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
270
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
271 /*
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
272 DC_API DCstruct* dcNewStruct (DCsize fieldCount, DCint alignment);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
273 DC_API void dcStructField (DCstruct* s, DCint type, DCint alignment, DCsize arrayLength);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
274 DC_API void dcSubStruct (DCstruct* s, DCsize fieldCount, DCint alignment, DCsize arrayLength);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
275 DC_API void dcCloseStruct (DCstruct* s);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
276 DC_API DCsize dcStructSize (DCstruct* s);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
277 DC_API DCsize dcStructAlignment(DCstruct* s);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
278 DC_API void dcFreeStruct (DCstruct* s);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
279
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
280 DC_API DCstruct* dcDefineStruct (const char* signature);
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
281 */
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
282