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
> <[email protected]> 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
>>>
>>> ______________________________________________
>>> [email protected] mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>>
>>
>
>
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel