On Sep 15, 2012, at 11:28 AM, Simon Knapp wrote: > Hi Simon, > > Thanks for your advice, but I'm still not clear. In my case I don't > want to modify the result - the integer acts as a handle for indexing > an array in later calls back into my library. > > As I understand it, returning result like > > SEXP func(SEXP arg) {return arg;} > > would not copy arg and hence I would have two pointers to the same > object immediately after the call... and (if this is the case) I'm not > sure whether this is OK. >
My answer is was, yes, it's ok. > Just to be clear, are you saying that the proper way to do things is > (at the end of my function in the original post): > > SET_SLOT(ans, Rf_install("myInteger"), duplicate(thingysInteger)); > return ans; > > rather than > > SET_SLOT(ans, Rf_install("myInteger"), thingysInteger); > return ans; > > ? > No, because you're not modifying anything in that case. > The last thing I'm not clear on is if it is OK to create a new SEXP > (with a call like duplicate) in a call to another function (as in the > first case above) or does this leave it unprotected? > Most functions (but not all - a notable exception is eval) protect their arguments, so it's ok in most cases. But this is no different than any other SEXP result - not specific to duplicate() in particular. Cheers, Simon > Thanx again for your help, > Simon > > On Sat, Sep 15, 2012 at 10:40 PM, Simon Urbanek > <simon.urba...@r-project.org> wrote: >> >> On Sep 14, 2012, at 11:10 PM, Simon Knapp wrote: >> >>> Hi List, >>> >>> I'd imagine this is a question that has been answered before, but I >>> can't seem to track it down, sorry for the duplication if it has. >>> >>> I am writing an interface for a C library and want to return an S4 >>> class from the 'constructing' method. One of the slots of the argument >>> to be returned will be filled with one of the arguments passed to the >>> function. My question is about whether I can directly pass arguments >>> to the function directly to slots of the returned object (or to a >>> return value more generally for that matter), or whether I have to >>> copy them. If it is the latter, then how may I do this. The question >>> is phrased in the following (simplified) code. >>> >>> int constructThingy(int thingysInteger); >>> >>> SEXP constructThingy(SEXP thingysInteger) { >>> SEXP ans, TClass, ti; >>> if(!isInteger(thingysInteger)) error("thingysIntegermust be an integer."); >>> if(constructThingy(INTEGER(thingysInteger)[0])) error("error in >>> getting a thingy"); >>> TClass = MAKE_CLASS("thingy"); >>> PROTECT(ans = NEW_OBJECT(TClass)); >>> >>> >>> // *****QUESTION STARTS HERE***** >>> // CAN I SAY: >>> SET_SLOT(ans, Rf_install("myInteger"), thingysInteger); >>> >>> // IF NOT, CAN I SAY >>> SET_SLOT(ans, Rf_install("myInteger"), AS_INTEGER(thingysInteger)); >>> >>> // OR DO I NEED TO SAY >>> PROTECT(ti = allocVector(INTSXP, 1)); INTEGER(pns)[0] = >>> INTEGER(thingysInteger)[0]; >>> SET_SLOT(ans, Rf_install("myInteger"), ti); >>> // *****END OF QUESTION***** >>> >>> UNPROTECT(1); // or UNPROTECT(2) in latter case. >>> return ans; >>> } >>> >>> >>> >>> I think this is the same as asking whether the following is OK: >>> >>> SEXP func(SEXP arg) { >>> return arg; >>> } >>> >> >> Yes. >> >> In fact if you wanted to duplicate (e.g, if you want to modify an incoming >> argument and return the modified result), the proper way would be to use >> duplicate() and not the contortions your were trying. >> >> Cheers, >> Simon >> >> >>> >>> >>> >>> >>> Thanks in advance, >>> Simon >>> >>> ______________________________________________ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >>> >> > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel