[C++ to R] SWIG objects into lists

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[C++ to R] SWIG objects into lists

Akira
Hi,

I wrapped a C++ library to R.
I noticed I cannot add the wrapped C++ classes into lists...
I guess this is because of the copying policy (SWIG uses SEXP and therefore the objects have a different copying policy. This is of course great on the one hand, because we normally do not want to copy the C++ object everytime we give it to a function, but probably not good on the other hand since R seems to insist on copying if you add the objects to a list).

I will make clear what I mean with an example:

I created an instance of a wrapped C++ class in R

> test = WrappedClass()
> test
An object of class "_p_WrappedClass"
Slot "ref":
<pointer: 0x5fa4440>


If I give this instance to a function an change it, the changes will be made on the original object (This is exactly what I want).

But if I want to put this object into a list the following happens:

> list(test)
[[1]]
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for signature ‘"function"’


I guess, as descripted above, that he tries to copy it and fails...
So is there any possibility to create objects that can be added to lists?
SWIG creates S4 classes. Would my goal be for example achievable with R6 classes?
And if so, can I create them with SWIG?

Thanks in advance and best regards!
Akira
Reply | Threaded
Open this post in threaded view
|

Re: [C++ to R] SWIG objects into lists

Richard Beare
We are certainly using lists of wrapped classes in the SimpleITK R wrappers.

I suspect that the call you are making is attempting to coerce test to a list, rather than creating a list of 1 wrapped class. Do all of the following give a similar error?

l1 <- list(a=test)

l2 <- replicate(3, WrappedClass())

l3 <- list()
l3[[1]] <- test

l4 <- list(test, test)

Swig creates S4 classes for C++ objects. If the objects have methods it will create a reference class-like interface to them. The interface generator pre-dates R6 classes, but it looks similar. You end up being able
to call methods using syntax like:

test$Method1()


On Tue, Jun 21, 2016 at 6:41 PM, Akira <[hidden email]> wrote:
Hi,

I wrapped a C++ library to R.
I noticed I cannot add the wrapped C++ classes into lists...
I guess this is because of the copying policy (SWIG uses SEXP and therefore
the objects have a different copying policy. This is of course great on the
one hand, because we normally do not want to copy the C++ object everytime
we give it to a function, but probably not good on the other hand since R
seems to insist on copying if you add the objects to a list).

I will make clear what I mean with an example:

I created an instance of a wrapped C++ class in R

> test = WrappedClass()
> test
An object of class "_p_WrappedClass"
Slot "ref":
<pointer: 0x5fa4440>


If I give this instance to a function an change it, the changes will be made
on the original object (This is exactly what I want).

But if I want to put this object into a list the following happens:

> list(test)
[[1]]
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for
signature ‘"function"’


I guess, as descripted above, that he tries to copy it and fails...
So is there any possibility to create objects that can be added to lists?
SWIG creates S4 classes. Would my goal be for example achievable with R6
classes?
And if so, can I create them with SWIG?

Thanks in advance and best regards!
Akira




--
View this message in context: http://swig.10945.n7.nabble.com/C-to-R-SWIG-objects-into-lists-tp14805.html
Sent from the swig-user mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user


------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Reply | Threaded
Open this post in threaded view
|

Re: [C++ to R] SWIG objects into lists

Akira
Thanks a lot for your answer!

There was no error when I saved the list into a variable name, but in all the variants I get the same error when I just type the list's name into the interpreter:

> l =  list(test)
> l
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for signature ‘"function"’

I have the same problem when I just call the print function on the R objects

> print(test)
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for signature ‘"function"’

BUT for lists: Even though I get this error when I put the wrapped class into a list and type the name into the interpreter, the object is actually in the list! I can call its methods without problems.

> l =  list(test)
> l[[1]]$callMethod()
An object of class "_p_OutputClass"
Slot "ref":
<pointer: 0x5fa4440>

So I am somewhere in between relieved (the error seems not to be too bad) and confused. I am especially confused because the following works totally fine:

> l =  list(test)
> print(l)
[[1]]
An object of class "_p_WrappedClass"
Slot "ref":
<pointer: 0x5fa4440>

Do you have and idea what the problem is?
Thanks a lot again and have a nice day
Akira
Reply | Threaded
Open this post in threaded view
|

Re: [C++ to R] SWIG objects into lists

Richard Beare
It looks like an error with the print dispatching, which is strange as swig provides some defaults. You could try setting your own print and show methods to see if it helps

  setMethod('show', '_p_OutputClass', function(object) print(object@ref))
  setMethod('print', '_p_OutputClass', function(x, ...)cat(x@ref))


It often pays to dig around in the dispatching code that has been generated to see if it is sensible.

getMethod('$', class(test))


will give you a list of methods that have been wrapped. Then you can trace whether there are name clashes or anything else weird happening.

On Tue, Jun 21, 2016 at 8:07 PM, Akira <[hidden email]> wrote:
Thanks a lot for your answer!

There was no error when I saved the list into a variable name, but in all
the variants I get the same error when I just type the list's name into the
interpreter:

> l =  list(test)
> l
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for
signature ‘"function"’

I have the same problem when I just call the print function on the R objects

> print(test)
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘addNextMethod’ for
signature ‘"function"’

BUT for lists: Even though I get this error when I put the wrapped class
into a list and type the name into the interpreter, the object is actually
in the list! I can call its methods without problems.

> l =  list(test)
> l[[1]]$callMethod()
An object of class "_p_OutputClass"
Slot "ref":
<pointer: 0x5fa4440>

So I am somewhere in between relieved (the error seems not to be too bad)
and confused. I am especially confused because the following works totally
fine:

> l =  list(test)
> print(l)
[[1]]
An object of class "_p_WrappedClass"
Slot "ref":
<pointer: 0x5fa4440>

Do you have and idea what the problem is?
Thanks a lot again and have a nice day
Akira




--
View this message in context: http://swig.10945.n7.nabble.com/C-to-R-SWIG-objects-into-lists-tp14805p14807.html
Sent from the swig-user mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user


------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Reply | Threaded
Open this post in threaded view
|

Re: [C++ to R] SWIG objects into lists

Akira
Hi,

thankyou very much for your help :)
Actually, R finds the default print SWIG provides, it just failes while executing.
SWIG provides the following:

setMethod('print', 'ExternalReference',
function(x) {print(as(x, "character"))})

And every class inherits from ExternalReference.
And if I directly call

> print(as(test, "character"))

it failes with the same error. If I provide another print function for ExternalReference, I don't have the error anymore.

Thanks a lot again :)
Akira