Embed google-protobuf in extension

I need urgent help in wrapping google-protobuf in my extension’s namespace. The google-protobuf’s gem has C extension. I have created a new repo from google-protobuf and changed the package name

“Google::Protobuf”=>“Solutionario::Sentio::Google::Protobuf”

Repo link: GitHub - sutharsentio/sentio-protobuf
and I have cross-compiled it for windows.

I have created a simple SU extension which loads modified google-protobuf. But due to some errors I am not to load it.

Extension:
sketchup-embed-lib.zip (482.2 KB)

Any help would be appreciated. @tt_su

You are using File.dirname(__FILE__) many places. Ruby 2.x defines a global __dir__ method from the Kernel mixin module (which is mixed into Object.)

So …

require(File.join(File.dirname(__FILE__), 'protobuf/descriptor_dsl'))

can become …

require(File.join(__dir__, 'protobuf/descriptor_dsl'))

It is not needed to use Sketchup.require for plain rb files unless you plan to encrypt the whole code base.


The Ruby version that SketchUp has shipped with are:

  • 2.0.0
  • 2.2.4
  • 2.5.5
  • 2.7.2

(You’ve used another set of versions.)


The file for you example extension is not correct. The extension registrar (‘lib-embedder.rb’) should be name “Solutionario_SentioProtoBuf.rb” and the folder (“source”) should have the same name.

See Technical Requirements section of Extension Development Best Practices.


The wrapping looks correct at the bottom of the protocol.c file.

What errors ?

EDIT, okay I see that the C file will not load into SU2022. But get no more information …

Started loading google protobuf
Loading:C:/Users/Dan/AppData/Roaming/SketchUp/SketchUp 2022/SketchUp/Plugins/source/lib/google/2.7/protobuf_c
Could not load:C:/Users/Dan/AppData/Roaming/SketchUp/SketchUp 2022/SketchUp/Plugins/source/lib/google/2.7/protobuf_c

First of all Thanks for looking into it.
Right now I am checking it in SU2019. Once it is fixed I can make it work for the other versions.

I have made this plugin just to check loading issues with library.
In SU2019 the protobuf.so loads but it fails to find some methods.

Following is the error from my original SU extension

Error Loading File C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf/descriptor_pb.rb
Error: #<NoMethodError: undefined method `build' for #<Solutionario::Sentio::Google::Protobuf::DescriptorPool:0x0000020a37653b08>>
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf/descriptor_pb.rb:7:in `<top (required)>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf/descriptor_dsl.rb:6:in `require'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf/descriptor_dsl.rb:6:in `<top (required)>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf.rb:58:in `require'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/lib/google-protobuf/lib/google/protobuf.rb:58:in `<top (required)>'
C:/Program Files/SketchUp/SketchUp 2019/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:59:in `require'
C:/Program Files/SketchUp/SketchUp 2019/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:59:in `require'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/ruby/sentioloader.rb:536:in `load_scripts'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/ruby/sentioloader.rb:520:in `lazy_load'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/ruby/sentioloader.rb:589:in `<module:Sentio>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/ruby/sentioloader.rb:2:in `<module:Solutionario>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio/ruby/sentioloader.rb:1:in `<top (required)>'
C:/Program Files/SketchUp/SketchUp 2019/Tools/extensions.rb:197:in `require'
C:/Program Files/SketchUp/SketchUp 2019/Tools/extensions.rb:197:in `load'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio.rb:52:in `register_extension'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio.rb:52:in `<module:Sentio>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio.rb:24:in `<module:Solutionario>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/sentio.rb:23:in `<top (required)>'
Summary

This text will be hidden

Maybe some files aren’t loaded?

I see that the require statements in the modified gem: sentio-protobuf/descriptor_dsl.rb at 50ea02c1d4414e2405980896b22b8d115948eead · sutharsentio/sentio-protobuf · GitHub

All of these would need to be relative to your extension installation (the Plugin directory where the extension is installed)

1 Like

This change is already there in the extension.

Yes that line …

require 'google/protobuf/descriptor_pb'

… would need to change to …

Sketchup.require File.join(__dir__, 'google/protobuf/descriptor_pb')

Also in the "descriptor_dsl.rb" file there are a number of method calls (such as line 57) to another namepsace, ie …

          serialized = Google::Protobuf::FileDescriptorProto.encode(proto)

Since the Google namespace is no longer at the top level, …
and is also not at the same level as class Google::Protobuf::Internal::Builder (from which the call is made,) perhaps the call cannot find the Google::Protobuf::FileDescriptorProto object ?

This could occur in several places in that file.

You may need to search and replace through all the rb files and requalify such references by search and replace "Google::" with "Solutionario::Sentio::Google::"

After making the suggested changes I am getting the following error

Error Loading File D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf/descriptor_pb.rb
Error: #<NoMethodError: undefined method `build' for #<Solutionario::Sentio::Google::Protobuf::DescriptorPool:0x000001d8cc3ea5e8>>
D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf/descriptor_pb.rb:7:in `<top (required)>'
D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf/descriptor_dsl.rb:6:in `require'
D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf/descriptor_dsl.rb:6:in `<top (required)>'
D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf.rb:58:in `require'
D:/UnityPlayGround/sketchup-embed-lib/source/lib/google/protobuf.rb:58:in `<top (required)>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/source/main.rb:8:in `require'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/source/main.rb:8:in `lazy_load'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/source/main.rb:14:in `<module:Sentio>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/source/main.rb:2:in `<module:Solutionario>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/source/main.rb:1:in `<top (required)>'
C:/Program Files/SketchUp/SketchUp 2019/Tools/extensions.rb:197:in `require'
C:/Program Files/SketchUp/SketchUp 2019/Tools/extensions.rb:197:in `load'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/lib-embedder.rb:37:in `register_extension'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/lib-embedder.rb:37:in `<module:Sentio>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/lib-embedder.rb:24:in `<module:Solutionario>'
C:/Users/Ajay/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/lib-embedder.rb:23:in `<top (required)>'

The ‘build’ method is defined in descriptor_dsl at the end of the file. But descriptor_pb is loaded before it as some classes are defined in it that is needed by descriptor_dsl. I may be wrong.

Attached extension after changes:
sketchup-embed-lib.zip (482.6 KB)

You can check $LOADED_FEATURES to get some insight to the order of how files are loaded.