1 /* ----------------------------------------------------------------------------- 2 * typemaps.i 3 * 4 * Pointer and reference handling typemap library 5 * 6 * These mappings provide support for input/output arguments and common 7 * uses for C/C++ pointers and C++ references. 8 * ----------------------------------------------------------------------------- */ 9 10 /* 11 INPUT typemaps 12 -------------- 13 14 These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is 15 passed by value instead of reference. 16 17 The following typemaps can be applied to turn a pointer or reference into a simple 18 input value. That is, instead of passing a pointer or reference to an object, 19 you would use a real value instead. 20 21 bool *INPUT, bool &INPUT 22 signed char *INPUT, signed char &INPUT 23 unsigned char *INPUT, unsigned char &INPUT 24 short *INPUT, short &INPUT 25 unsigned short *INPUT, unsigned short &INPUT 26 int *INPUT, int &INPUT 27 unsigned int *INPUT, unsigned int &INPUT 28 long *INPUT, long &INPUT 29 unsigned long *INPUT, unsigned long &INPUT 30 long long *INPUT, long long &INPUT 31 unsigned long long *INPUT, unsigned long long &INPUT 32 float *INPUT, float &INPUT 33 double *INPUT, double &INPUT 34 35 To use these, suppose you had a C function like this : 36 37 double fadd(double *a, double *b) { 38 return *a+*b; 39 } 40 41 You could wrap it with SWIG as follows : 42 43 %include <typemaps.i> 44 double fadd(double *INPUT, double *INPUT); 45 46 or you can use the %apply directive : 47 48 %include <typemaps.i> 49 %apply double *INPUT { double *a, double *b }; 50 double fadd(double *a, double *b); 51 52 In Go you could then use it like this: 53 answer := modulename.Fadd(10.0, 20.0) 54 55 There are no char *INPUT typemaps, however you can apply the signed 56 char * typemaps instead: 57 %include <typemaps.i> 58 %apply signed char *INPUT {char *input}; 59 void f(char *input); 60 */ 61 62 %define INPUT_TYPEMAP(TYPE, GOTYPE) 63 %typemap(gotype) TYPE *INPUT, TYPE &INPUT "GOTYPE" 64 65 %typemap(in) TYPE *INPUT, TYPE &INPUT 66 %{ $1 = ($1_ltype)&$input; %} 67 68 %typemap(out) TYPE *INPUT, TYPE &INPUT "" 69 70 %typemap(freearg) TYPE *INPUT, TYPE &INPUT "" 71 72 %typemap(argout) TYPE *INPUT, TYPE &INPUT "" 73 74 // %typemap(typecheck) TYPE *INPUT = TYPE; 75 // %typemap(typecheck) TYPE &INPUT = TYPE; 76 %enddef 77 78 INPUT_TYPEMAP(bool, bool); 79 INPUT_TYPEMAP(signed char, int8); 80 INPUT_TYPEMAP(char, byte); 81 INPUT_TYPEMAP(unsigned char, byte); 82 INPUT_TYPEMAP(short, int16); 83 INPUT_TYPEMAP(unsigned short, uint16); 84 INPUT_TYPEMAP(int, int); 85 INPUT_TYPEMAP(unsigned int, uint); 86 INPUT_TYPEMAP(long, int64); 87 INPUT_TYPEMAP(unsigned long, uint64); 88 INPUT_TYPEMAP(long long, int64); 89 INPUT_TYPEMAP(unsigned long long, uint64); 90 INPUT_TYPEMAP(float, float32); 91 INPUT_TYPEMAP(double, float64); 92 93 #undef INPUT_TYPEMAP 94 95 // OUTPUT typemaps. These typemaps are used for parameters that 96 // are output only. An array replaces the c pointer or reference parameter. 97 // The output value is returned in this array passed in. 98 99 /* 100 OUTPUT typemaps 101 --------------- 102 103 The following typemaps can be applied to turn a pointer or reference 104 into an "output" value. When calling a function, no input value would 105 be given for a parameter, but an output value would be returned. This 106 works by a Go slice being passed as a parameter where a c pointer or 107 reference is required. As with any Go function, the array is passed 108 by reference so that any modifications to the array will be picked up 109 in the calling function. Note that the array passed in MUST have at 110 least one element, but as the c function does not require any input, 111 the value can be set to anything. 112 113 bool *OUTPUT, bool &OUTPUT 114 signed char *OUTPUT, signed char &OUTPUT 115 unsigned char *OUTPUT, unsigned char &OUTPUT 116 short *OUTPUT, short &OUTPUT 117 unsigned short *OUTPUT, unsigned short &OUTPUT 118 int *OUTPUT, int &OUTPUT 119 unsigned int *OUTPUT, unsigned int &OUTPUT 120 long *OUTPUT, long &OUTPUT 121 unsigned long *OUTPUT, unsigned long &OUTPUT 122 long long *OUTPUT, long long &OUTPUT 123 unsigned long long *OUTPUT, unsigned long long &OUTPUT 124 float *OUTPUT, float &OUTPUT 125 double *OUTPUT, double &OUTPUT 126 127 For example, suppose you were trying to wrap the modf() function in the 128 C math library which splits x into integral and fractional parts (and 129 returns the integer part in one of its parameters): 130 131 double modf(double x, double *ip); 132 133 You could wrap it with SWIG as follows : 134 135 %include <typemaps.i> 136 double modf(double x, double *OUTPUT); 137 138 or you can use the %apply directive : 139 140 %include <typemaps.i> 141 %apply double *OUTPUT { double *ip }; 142 double modf(double x, double *ip); 143 144 The Go output of the function would be the function return value and the 145 value in the single element array. In Go you would use it like this: 146 147 ptr := []float64{0.0} 148 fraction := modulename.Modf(5.0,ptr) 149 150 There are no char *OUTPUT typemaps, however you can apply the signed 151 char * typemaps instead: 152 %include <typemaps.i> 153 %apply signed char *OUTPUT {char *output}; 154 void f(char *output); 155 */ 156 157 %define OUTPUT_TYPEMAP(TYPE, GOTYPE) 158 %typemap(gotype) TYPE *OUTPUT, TYPE &OUTPUT %{[]GOTYPE%} 159 160 %typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp) 161 { 162 if ($input.len == 0) { 163 _swig_gopanic("array must contain at least 1 element"); 164 } 165 $1 = &temp; 166 } 167 168 %typemap(out) TYPE *OUTPUT, TYPE &OUTPUT "" 169 170 %typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT "" 171 172 %typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT 173 { 174 TYPE* a = (TYPE *) $input.array; 175 a[0] = temp$argnum; 176 } 177 178 %enddef 179 180 OUTPUT_TYPEMAP(bool, bool); 181 OUTPUT_TYPEMAP(signed char, int8); 182 OUTPUT_TYPEMAP(char, byte); 183 OUTPUT_TYPEMAP(unsigned char, byte); 184 OUTPUT_TYPEMAP(short, int16); 185 OUTPUT_TYPEMAP(unsigned short, uint16); 186 OUTPUT_TYPEMAP(int, int); 187 OUTPUT_TYPEMAP(unsigned int, uint); 188 OUTPUT_TYPEMAP(long, int64); 189 OUTPUT_TYPEMAP(unsigned long, uint64); 190 OUTPUT_TYPEMAP(long long, int64); 191 OUTPUT_TYPEMAP(unsigned long long, uint64); 192 OUTPUT_TYPEMAP(float, float32); 193 OUTPUT_TYPEMAP(double, float64); 194 195 #undef OUTPUT_TYPEMAP 196 197 /* 198 INOUT typemaps 199 -------------- 200 201 Mappings for a parameter that is both an input and an output parameter 202 203 The following typemaps can be applied to make a function parameter both 204 an input and output value. This combines the behavior of both the 205 "INPUT" and "OUTPUT" typemaps described earlier. Output values are 206 returned as an element in a Go slice. 207 208 bool *INOUT, bool &INOUT 209 signed char *INOUT, signed char &INOUT 210 unsigned char *INOUT, unsigned char &INOUT 211 short *INOUT, short &INOUT 212 unsigned short *INOUT, unsigned short &INOUT 213 int *INOUT, int &INOUT 214 unsigned int *INOUT, unsigned int &INOUT 215 long *INOUT, long &INOUT 216 unsigned long *INOUT, unsigned long &INOUT 217 long long *INOUT, long long &INOUT 218 unsigned long long *INOUT, unsigned long long &INOUT 219 float *INOUT, float &INOUT 220 double *INOUT, double &INOUT 221 222 For example, suppose you were trying to wrap the following function : 223 224 void neg(double *x) { 225 *x = -(*x); 226 } 227 228 You could wrap it with SWIG as follows : 229 230 %include <typemaps.i> 231 void neg(double *INOUT); 232 233 or you can use the %apply directive : 234 235 %include <typemaps.i> 236 %apply double *INOUT { double *x }; 237 void neg(double *x); 238 239 This works similarly to C in that the mapping directly modifies the 240 input value - the input must be an array with a minimum of one element. 241 The element in the array is the input and the output is the element in 242 the array. 243 244 x := []float64{5.0} 245 Neg(x); 246 247 The implementation of the OUTPUT and INOUT typemaps is different to 248 other languages in that other languages will return the output value 249 as part of the function return value. This difference is due to Go 250 being a typed language. 251 252 There are no char *INOUT typemaps, however you can apply the signed 253 char * typemaps instead: 254 %include <typemaps.i> 255 %apply signed char *INOUT {char *inout}; 256 void f(char *inout); 257 */ 258 259 %define INOUT_TYPEMAP(TYPE, GOTYPE) 260 %typemap(gotype) TYPE *INOUT, TYPE &INOUT %{[]GOTYPE%} 261 262 %typemap(in) TYPE *INOUT, TYPE &INOUT { 263 if ($input.len == 0) { 264 _swig_gopanic("array must contain at least 1 element"); 265 } 266 $1 = ($1_ltype) $input.array; 267 } 268 269 %typemap(out) TYPE *INOUT, TYPE &INOUT "" 270 271 %typemap(freearg) TYPE *INOUT, TYPE &INOUT "" 272 273 %typemap(argout) TYPE *INOUT, TYPE &INOUT "" 274 275 %enddef 276 277 INOUT_TYPEMAP(bool, bool); 278 INOUT_TYPEMAP(signed char, int8); 279 INOUT_TYPEMAP(char, byte); 280 INOUT_TYPEMAP(unsigned char, byte); 281 INOUT_TYPEMAP(short, int16); 282 INOUT_TYPEMAP(unsigned short, uint16); 283 INOUT_TYPEMAP(int, int); 284 INOUT_TYPEMAP(unsigned int, uint); 285 INOUT_TYPEMAP(long, int64); 286 INOUT_TYPEMAP(unsigned long, uint64); 287 INOUT_TYPEMAP(long long, int64); 288 INOUT_TYPEMAP(unsigned long long, uint64); 289 INOUT_TYPEMAP(float, float32); 290 INOUT_TYPEMAP(double, float64); 291 292 #undef INOUT_TYPEMAP 293