Ruby 2.7: rb_define_method and C++

Hey,

I'm the maintainer of the Rice gem[0] which provides a higher level way for exposing C++ APIs into Ruby, and I've got a problem getting Rice to work with Ruby 2.7 and wondering if I can get some help or pointers.

The short of it is, rb_define_method, when compiled under C++, is now redefined as a templated struct that takes the arity parameter as the template argument to pick the right overload at compile time[1]. This has led to a straight up compilation error in Rice under Ruby 2.7 [2] because as a C++ wrapper library, Rice builds up a wrapper object around each defined method to properly wrap and convert parameters and return values to and from Ruby, as well as providing a path from a templated C++ function or method to a plain C-usable function. That wrapper object is then provided to rb_define_method to properly expose the requested function/method to Ruby [3].

From what I can see, rb_define_method is now completely redefined to be this templated macro and I have found no way to directly call the underlying, original function. Does anyone here know why this change was made, if there were thoughts about keeping this function exposed for dynamic use, or if it still is, how I can call it (I've read through the source a few times, tried a few different defines, nothing seems to work)?

Thanks

Jason

[0] https://github.com/jasonroelofs/rice
[1] https://github.com/ruby/ruby/commit/9c0d5e51cb3726455560c34ad595ab82f651da48#diff-3b256c5581538dcd834697c766a2b1aaR2770
[2] https://github.com/jasonroelofs/rice/issues/119
[3] https://github.com/jasonroelofs/rice/blob/master/rice/detail/method_data.cpp#L78

I noticed that rice stopped working when I upgraded to 2.7.0. I never had that problem before, and I always build from the sources, using ./configure --enable-shared. It would be nice to get rice working again.

···

On 12/28/19 6:59 PM, Jason Roelofs wrote:

Hey,

I'm the maintainer of the Rice gem[0] which provides a higher level way for exposing C++ APIs into Ruby, and I've got a problem getting Rice to work with Ruby 2.7 and wondering if I can get some help or pointers.

The short of it is, rb_define_method, when compiled under C++, is now redefined as a templated struct that takes the arity parameter as the template argument to pick the right overload at compile time[1]. This has led to a straight up compilation error in Rice under Ruby 2.7 [2] because as a C++ wrapper library, Rice builds up a wrapper object around each defined method to properly wrap and convert parameters and return values to and from Ruby, as well as providing a path from a templated C++ function or method to a plain C-usable function. That wrapper object is then provided to rb_define_method to properly expose the requested function/method to Ruby [3].

From what I can see, rb_define_method is now completely redefined to be this templated macro and I have found no way to directly call the underlying, original function. Does anyone here know why this change was made, if there were thoughts about keeping this function exposed for dynamic use, or if it still is, how I can call it (I've read through the source a few times, tried a few different defines, nothing seems to work)?

Thanks

Jason

[0] GitHub - jasonroelofs/rice: Ruby Interface for C++ Extensions
[1] Check method functions in C++ · ruby/ruby@9c0d5e5 · GitHub
[2] Installation fails with Ruby 2.7 · Issue #119 · jasonroelofs/rice · GitHub
[3] https://github.com/jasonroelofs/rice/blob/master/rice/detail/method_data.cpp#L78

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Please file an issue on bugs.ruby-lang.org or contact nobu directly... You won't get traction here.

···

On Dec 28, 2019, at 16:59, Jason Roelofs <jasongroelofs@gmail.com> wrote:

Hey,

I'm the maintainer of the Rice gem[0] which provides a higher level way for exposing C++ APIs into Ruby, and I've got a problem getting Rice to work with Ruby 2.7 and wondering if I can get some help or pointers.

The short of it is, rb_define_method, when compiled under C++, is now redefined as a templated struct that takes the arity parameter as the template argument to pick the right overload at compile time[1]. This has led to a straight up compilation error in Rice under Ruby 2.7 [2] because as a C++ wrapper library, Rice builds up a wrapper object around each defined method to properly wrap and convert parameters and return values to and from Ruby, as well as providing a path from a templated C++ function or method to a plain C-usable function. That wrapper object is then provided to rb_define_method to properly expose the requested function/method to Ruby [3].

From what I can see, rb_define_method is now completely redefined to be this templated macro and I have found no way to directly call the underlying, original function. Does anyone here know why this change was made, if there were thoughts about keeping this function exposed for dynamic use, or if it still is, how I can call it (I've read through the source a few times, tried a few different defines, nothing seems to work)?

Thanks

Jason

[0] GitHub - jasonroelofs/rice: Ruby Interface for C++ Extensions
[1] Check method functions in C++ · ruby/ruby@9c0d5e5 · GitHub
[2] Installation fails with Ruby 2.7 · Issue #119 · jasonroelofs/rice · GitHub
[3] https://github.com/jasonroelofs/rice/blob/master/rice/detail/method_data.cpp#L78

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

We got a fix in place and Rice 2.2.0 is out to fix this error.

Jason