1 /* ----------------------------------------------------------------------------- 2 * reference.i 3 * 4 * Accept Perl references as pointers 5 * ----------------------------------------------------------------------------- */ 6 7 /* 8 The following methods make Perl references work like simple C 9 pointers. References can only be used for simple input/output 10 values, not C arrays however. It should also be noted that 11 REFERENCES are specific to Perl and not supported in other 12 scripting languages at this time. 13 14 int *REFERENCE 15 short *REFERENCE 16 long *REFERENCE 17 unsigned int *REFERENCE 18 unsigned short *REFERENCE 19 unsigned long *REFERENCE 20 unsigned char *REFERENCE 21 float *REFERENCE 22 double *REFERENCE 23 24 For example, suppose you were trying to wrap the following function : 25 26 void neg(double *x) { 27 *x = -(*x); 28 } 29 30 You could wrap it with SWIG as follows : 31 32 %include reference.i 33 void neg(double *REFERENCE); 34 35 or you can use the %apply directive : 36 37 %include reference.i 38 %apply double *REFERENCE { double *x }; 39 void neg(double *x); 40 41 Unlike the INOUT mapping described in typemaps.i, this approach directly 42 modifies the value of a Perl reference. Thus, you could use it 43 as follows : 44 45 $x = 3; 46 neg(\$x); 47 print "$x\n"; # Should print out -3. 48 49 */ 50 51 %typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue) 52 { 53 SV *tempsv; 54 if (!SvROK($input)) { 55 SWIG_croak("expected a reference"); 56 } 57 tempsv = SvRV($input); 58 if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { 59 printf("Received %d\n", SvTYPE(tempsv)); 60 SWIG_croak("Expected a double reference."); 61 } 62 dvalue = SvNV(tempsv); 63 $1 = &dvalue; 64 } 65 66 %typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue) 67 { 68 SV *tempsv; 69 if (!SvROK($input)) { 70 SWIG_croak("expected a reference"); 71 } 72 tempsv = SvRV($input); 73 if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { 74 SWIG_croak("expected a double reference"); 75 } 76 dvalue = (float) SvNV(tempsv); 77 $1 = &dvalue; 78 } 79 80 %typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue) 81 { 82 SV *tempsv; 83 if (!SvROK($input)) { 84 SWIG_croak("expected a reference"); 85 } 86 tempsv = SvRV($input); 87 if (!SvIOK(tempsv)) { 88 SWIG_croak("expected an integer reference"); 89 } 90 dvalue = SvIV(tempsv); 91 $1 = &dvalue; 92 } 93 94 %typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue) 95 { 96 SV *tempsv; 97 if (!SvROK($input)) { 98 SWIG_croak("expected a reference"); 99 } 100 tempsv = SvRV($input); 101 if (!SvIOK(tempsv)) { 102 SWIG_croak("expected an integer reference"); 103 } 104 dvalue = (short) SvIV(tempsv); 105 $1 = &dvalue; 106 } 107 %typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue) 108 { 109 SV *tempsv; 110 if (!SvROK($input)) { 111 SWIG_croak("expected a reference"); 112 } 113 tempsv = SvRV($input); 114 if (!SvIOK(tempsv)) { 115 SWIG_croak("expected an integer reference"); 116 } 117 dvalue = (long) SvIV(tempsv); 118 $1 = &dvalue; 119 } 120 %typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue) 121 { 122 SV *tempsv; 123 if (!SvROK($input)) { 124 SWIG_croak("expected a reference"); 125 } 126 tempsv = SvRV($input); 127 if (!SvIOK(tempsv)) { 128 SWIG_croak("expected an integer reference"); 129 } 130 dvalue = (unsigned int) SvUV(tempsv); 131 $1 = &dvalue; 132 } 133 %typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue) 134 { 135 SV *tempsv; 136 if (!SvROK($input)) { 137 SWIG_croak("expected a reference"); 138 } 139 tempsv = SvRV($input); 140 if (!SvIOK(tempsv)) { 141 SWIG_croak("expected an integer reference"); 142 } 143 dvalue = (unsigned short) SvUV(tempsv); 144 $1 = &dvalue; 145 } 146 %typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue) 147 { 148 SV *tempsv; 149 if (!SvROK($input)) { 150 SWIG_croak("expected a reference"); 151 } 152 tempsv = SvRV($input); 153 if (!SvIOK(tempsv)) { 154 SWIG_croak("expected an integer reference"); 155 } 156 dvalue = (unsigned long) SvUV(tempsv); 157 $1 = &dvalue; 158 } 159 160 %typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue) 161 { 162 SV *tempsv; 163 if (!SvROK($input)) { 164 SWIG_croak("expected a reference"); 165 } 166 tempsv = SvRV($input); 167 if (!SvIOK(tempsv)) { 168 SWIG_croak("expected an integer reference"); 169 } 170 dvalue = (unsigned char) SvUV(tempsv); 171 $1 = &dvalue; 172 } 173 174 %typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue) 175 { 176 SV *tempsv; 177 if (!SvROK($input)) { 178 SWIG_croak("expected a reference"); 179 } 180 tempsv = SvRV($input); 181 if (!SvIOK(tempsv)) { 182 SWIG_croak("expected an integer reference"); 183 } 184 dvalue = (signed char) SvIV(tempsv); 185 $1 = &dvalue; 186 } 187 188 %typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue) 189 { 190 SV *tempsv; 191 if (!SvROK($input)) { 192 SWIG_croak("expected a reference"); 193 } 194 tempsv = SvRV($input); 195 if (!SvIOK(tempsv)) { 196 SWIG_croak("expected an integer reference"); 197 } 198 dvalue = SvIV(tempsv) ? true : false; 199 $1 = &dvalue; 200 } 201 202 %typemap(typecheck) int *REFERENCE, int &REFERENCE, 203 short *REFERENCE, short &REFERENCE, 204 long *REFERENCE, long &REFERENCE, 205 signed char *REFERENCE, signed char &REFERENCE, 206 bool *REFERENCE, bool &REFERENCE 207 { 208 $1 = SvROK($input) && SvIOK(SvRV($input)); 209 } 210 %typemap(typecheck) double *REFERENCE, double &REFERENCE, 211 float *REFERENCE, float &REFERENCE 212 { 213 $1 = SvROK($input); 214 if($1) { 215 SV *tmpsv = SvRV($input); 216 $1 = SvNOK(tmpsv) || SvIOK(tmpsv); 217 } 218 } 219 %typemap(typecheck) unsigned int *REFERENCE, unsigned int &REFERENCE, 220 unsigned short *REFERENCE, unsigned short &REFERENCE, 221 unsigned long *REFERENCE, unsigned long &REFERENCE, 222 unsigned char *REFERENCE, unsigned char &REFERENCE 223 { 224 $1 = SvROK($input); 225 if($1) { 226 SV *tmpsv = SvRV($input); 227 $1 = SvUOK(tmpsv) || SvIOK(tmpsv); 228 } 229 } 230 231 %typemap(argout) double *REFERENCE, double &REFERENCE, 232 float *REFERENCE, float &REFERENCE 233 { 234 SV *tempsv; 235 tempsv = SvRV($arg); 236 if (!$1) SWIG_croak("expected a reference"); 237 sv_setnv(tempsv, (double) *$1); 238 } 239 240 %typemap(argout) int *REFERENCE, int &REFERENCE, 241 short *REFERENCE, short &REFERENCE, 242 long *REFERENCE, long &REFERENCE, 243 signed char *REFERENCE, signed char &REFERENCE, 244 bool *REFERENCE, bool &REFERENCE 245 { 246 SV *tempsv; 247 tempsv = SvRV($input); 248 if (!$1) SWIG_croak("expected a reference"); 249 sv_setiv(tempsv, (IV) *$1); 250 } 251 252 %typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE, 253 unsigned short *REFERENCE, unsigned short &REFERENCE, 254 unsigned long *REFERENCE, unsigned long &REFERENCE, 255 unsigned char *REFERENCE, unsigned char &REFERENCE 256 { 257 SV *tempsv; 258 tempsv = SvRV($input); 259 if (!$1) SWIG_croak("expected a reference"); 260 sv_setuv(tempsv, (UV) *$1); 261 } 262