From: barabba Date: 2007-03-15T06:50:09+09:00 Subject: Re: SWIG typemap for ta-lib On Mar 14, 11:45 am, "BENI" wrote: > Thanks for your lead. > It is lot clear now ... how to go about it. > Still I am fuzzy on a couple of things. > Could you pl guide.... > > > > > in ruby use it as > > closePrice = Array.new() > > data_inp = closePrice[0..399] > > data_arr = ModuleExp::TA_MA( data_inp, 30, ModuleExp::TA_MAType_SMA) > > So are you suggesting that i need not pass startIdx,endIdx in the > input. But these values I understand is required .. this is to > sometimes specify a range on which to run the function . > What I am confused about is ...ModuleExp::TA_MAType_SMA... is this a > constant that you are suggesting to pass along? > > > > > > > In .i file you should define > > %typemap(in)(int startIdx, > > int endIdx, > > const double inReal[] > > ) > > { > > > Check_Type($input, T_ARRAY); > > > /* Get the length of the array */ > > int size = RARRAY($input)->len; > > int i; > > $3 = (unsigned char*) malloc(size * sizeof(double)); > > $2 = size; > > $1 = 0; > > > // copy the ruby array in the new allocated buffer > > /* Get the first element in memory */ > > VALUE *ptr = RARRAY($input)->ptr; > > for (i=0; i < size; i++, ptr++) > > { > > /* Convert Ruby Object Fixnum to unsigned char */ > > $1[i]= (double)?????(*ptr); // here i don't remember the macro > > to convert something like FIX2INT for float > > } > > here I used $1[i]= NUM2DBL(*ptr); > is that OK? > > > } > > > %typemap(in)(int optInMAType, > > int *outBegIdx, > > int *outNbElement, > > double outReal[] > > ) > > { > > int out_beg_ix = 0; > > int out_n_ele = 0; > > double arr_res[400]; > > Here I need to dimensionise the arr_res to the size of the input > array instead of 400. So i need to get the size variable in the > previous typemap declaration. But how can i use the size variable > here... it was a local variable only. > > > > > > > $1 = NUM2INT(optInMAType); > > $2 = &out_beg_ix; > > $3 = &out_n_ele; > > &4 = arr_res; > > > } > > > %typemap(freearg) (int startIdx, > > int endIdx, > > const double inReal[], > > int optInTimePeriod, > > int optInMAType, > > int *outBegIdx, > > int *outNbElement, > > double outReal[]) { > > free((double *) $1); > > } > > > %typemap(out)TA_RetCode TA_MA( int startIdx, > > int endIdx, > > const double inReal[], > > int optInTimePeriod, > > int optInMAType, > > int *outBegIdx, > > int *outNbElement, > > double outReal[]) > > I did not get this one clearly.... TA_Retcode is the output type. > Can't i get it in ruby?Only thing that i am getting back here is the > outReal[] array i think. > > > { > > > int iStartIx = *arg6; > > int iLen = iStartIx + *arg7; > > > VALUE arr = rb_ary_new2(iLen); > > > for ( int i = iStartIx; i < iLen; i++ ) > > rb_ary_push(arr, INT2FIX((*arg8)[i])); > > $result = arr; > > the *arg8 contains floating point number so will INT2FIX work? > > > } > > > it is not tested but this give you the idea how to make the i file. > > > Regards > > Thanks again .. > > Regards Sorry for some errors. Your questions. If you use TA_MAType_SMA in the C function and you want to use it also in ruby, you have to export it. In Ruby I like to use all input parameters as function parameters. Out parameters on the left side as result. If you are also interested an TA_Retcode you have to change the typemap(out). Afterwards you can use in ruby this: ta_res, data_arr_out = ModuleExp::TA_MA( data_inp, 30, ModuleExp::TA_MAType_SMA) in .i file: %typemap(out)TA_RetCode TA_MA( int startIdx, int endIdx, const double inReal[], int optInTimePeriod, int optInMAType, int *outBegIdx, int *outNbElement, double outReal[] { int iStartIx = *arg6; int iLen = iStartIx + *arg7; VALUE arr_results = rb_ary_new2(2) // 2 elements as result rb_ary_push(arr_results, INT2FIX(result)); // first is TA_Retcode VALUE arr_data = rb_ary_new2(iLen); // data array for ( int i = iStartIx; i < iLen; i++ ) rb_ary_push(arr_data, rb_float_new((*arg8)[i])); rb_ary_push(arr_results, arr_data); // second array of data $result = arr_results } here you are right, INT2FIX doesn't work but rb_float_new should be. NUM2DBL for inputs should be also ok. If you need to pass startIdx,endIdx as input, you have to modify the typemap(in) %typemap(in)(const double inReal[]) { Check_Type($input, T_ARRAY); /* Get the length of the array */ int size = RARRAY($input)->len; int i; $1 = (unsigned char*) malloc(size * sizeof(double)); // copy the ruby array in the new allocated buffer /* Get the first element in memory */ VALUE *ptr = RARRAY($input)->ptr; for (i=0; i < size; i++, ptr++) { /* Convert Ruby Object Fixnum to unsigned char */ $1[i]= (double)NUM2DBL(*ptr); } } If you don't like a maxsize for output array, like double arr_res[MAX_OUT_DATA]; you can use: arg8 = (unsigned char*) malloc(size * sizeof(double)); inside %typemap(in)(const double inReal[]) I don't know if it is exact, but you can look inside the generated code if all is set like you want (I use swig with c++ and I expect a function called _wrap_TA_MA inside generated code). Don't forget to free arg8 in the typemap. Cheers Igor