• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Are Swig generated Ruby bindings compatible with Sketchup?

Scheduled Pinned Locked Moved Developers' Forum
13 Posts 7 Posters 2.9k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    metasim
    last edited by 5 Oct 2009, 00:57

    I'm hoping for someone to share some tips on how to efficiently link C++ code into Sketchup via the Ruby scripting engine. We are currently using Swig, which works fine in a stand-alone Ruby interpreter, but crashes Sketchup when loaded via the Sketchup console or as an extension.

    Our C++ library that has been successfully used via Ruby (and Python) via Swig generated bindings. The code has been tested pretty extensively on MacOS, and works fine with the the system supplied Ruby and with self-compiled versions of Ruby. However, the moment it is loaded into Sketchup via the console (i.e. "require 'mymodule'"), Sketchup crashes in the function "st_lookup".

    To simplify debugging, I created the standard "hello factorial world" test, and it too crashes sketchup:

    factorial.c

    
    int fact(int n) {
     if (n == 0)
     return 1;
     return (n * fact(n-1));
    }
    
    

    factorial.i

    
    %module factorial
    int fact(int n);
    
    

    extconf.rb

    
    require 'mkmf'
    create_makefile('factorial')
    
    

    So nothing fancy. To create the extension, first "swig -ruby factorial.i" is run, followed by "ruby extconf.rb && make". The resulting factorial.bundle file works fine in irb (via "require 'factorial'"). Try to load it in Sketchup via the Ruby Console, and Sketchup crashes with the following backtrace:

    
    Process;         SketchUp [26702]
    Path;            /Applications/Google SketchUp 7/SketchUp.app/Contents/MacOS/SketchUp
    Identifier;      com.google.sketchupfree7
    Version;         SketchUp 7 (7.1.4870)
    Code Type;       X86 (Native)
    Parent Process;  launchd [117]
    
    Date/Time;       2009-10-04 20;21;46.504 -0400
    OS Version;      Mac OS X 10.6.1 (10B504)
    Report Version;  6
    
    Interval Since Last Report;          194104 sec
    Crashes Since Last Report;           4
    Per-App Interval Since Last Report;  686 sec
    Per-App Crashes Since Last Report;   2
    Anonymous UUID;                      DD7CA090-136F-4294-89AE-7E0032D6E21A
    
    Exception Type;  EXC_CRASH (SIGABRT)
    Exception Codes; 0x0000000000000000, 0x0000000000000000
    Crashed Thread;  2
    
    Application Specific Information;
    abort() called
    
    Thread 0;  Dispatch queue; com.apple.main-thread
    0   libruby.1.dylib               	0x1d17f63e st_lookup + 15
    1   libruby.1.dylib               	0x1d1542fb rb_intern + 62
    2   libruby.1.dylib               	0x1d10b18e rb_define_module + 32
    3   factorial.bundle              	0x1a9c9452 Init_factorial + 38 (factorial_wrap.c;1480)
    4   com.google.rubyframework      	0x022971a6 dln_load + 285
    5   com.google.rubyframework      	0x022ad4c0 rb_require_safe + 623
    6   com.google.rubyframework      	0x022ace5d rb_f_require + 35
    7   com.google.rubyframework      	0x022a9ca2 call_cfunc + 315
    8   com.google.rubyframework      	0x022a90a4 rb_call0 + 1660
    9   com.google.rubyframework      	0x022aa83c rb_call + 700
    10  com.google.rubyframework      	0x022a2c3d rb_eval + 10073
    11  com.google.rubyframework      	0x0229d322 eval_node + 96
    12  com.google.rubyframework      	0x022ab60a eval + 1068
    13  com.google.rubyframework      	0x0229db8a rb_eval_string + 120
    14  com.google.rubyframework      	0x022a8211 rb_protect + 191
    15  com.google.rubyframework      	0x0229dbcb rb_eval_string_protect + 42
    16  com.google.sketchupfree7      	0x001967f5 0x1000 + 1660917
    17  com.google.sketchupfree7      	0x0017f552 0x1000 + 1566034
    18  com.google.sketchupfree7      	0x0017f5e2 0x1000 + 1566178
    19  com.apple.AppKit              	0x9883d14a -[NSApplication sendAction;to;from;] + 112
    20  com.apple.AppKit              	0x9891c891 -[NSControl sendAction;to;] + 108
    21  com.apple.AppKit              	0x9899614b -[NSTextField textDidEndEditing;] + 773
    22  com.apple.Foundation          	0x935c82fc _nsnote_callback + 345
    23  com.apple.CoreFoundation      	0x90fa4c29 __CFXNotificationPost + 905
    24  com.apple.CoreFoundation      	0x90fa465a _CFXNotificationPostNotification + 186
    25  com.apple.Foundation          	0x935bd120 -[NSNotificationCenter postNotificationName;object;userInfo;] + 128
    26  com.apple.AppKit              	0x989f157a -[NSTextView(NSPrivate) _giveUpFirstResponder;] + 553
    27  com.apple.AppKit              	0x989f1346 -[NSTextView(NSKeyBindingCommands) insertNewline;] + 531
    28  com.apple.AppKit              	0x989f1080 -[NSResponder doCommandBySelector;] + 77
    29  com.apple.AppKit              	0x989f0997 -[NSTextView doCommandBySelector;] + 240
    30  com.apple.AppKit              	0x989dfa1f -[NSKeyBindingManager(NSKeyBindingManager_MultiClients) interpretEventAsCommand;forClient;] + 1911
    31  com.apple.AppKit              	0x989e32bf -[NSTextInputContext handleEvent;] + 1604
    32  com.apple.AppKit              	0x989df088 -[NSView interpretKeyEvents;] + 209
    33  com.apple.AppKit              	0x989e2b45 -[NSTextView keyDown;] + 751
    34  com.apple.AppKit              	0x98914194 -[NSWindow sendEvent;] + 5757
    35  com.apple.AppKit              	0x9882cceb -[NSApplication sendEvent;] + 6431
    36  com.google.sketchupfree7      	0x00178aa1 0x1000 + 1538721
    37  com.apple.AppKit              	0x987c06fb -[NSApplication run] + 917
    38  com.apple.AppKit              	0x987b8735 NSApplicationMain + 574
    39  com.google.sketchupfree7      	0x00003772 0x1000 + 10098
    40  com.google.sketchupfree7      	0x00003699 0x1000 + 9881
    
    

    I've tried compiling against different versions of Ruby (matching the 1.8.5 that appears to be in Sketchup currently), and even looking through the ruby source at the implementation of "rb_intern" and call to "st_lookup" for inspiration, to no avail. So I'm hoping there's some brilliant developer out there who's figured out what this is all about and can help save my sanity. πŸ˜„

    Again, any thoughts or tips are appreciated.

    Thanks,

    Simeon

    1 Reply Last reply Reply Quote 0
    • C Offline
      Chris Fullmer
      last edited by 5 Oct 2009, 04:01

      This is all over my head. But I won't let that stop me from responding πŸ˜„

      The Ruby installed with SketchUp is a very minimal install. It is missing many major support files, methods, classes, etc., that might come with the full install. So I do not know what st_lookup is, but if it is a method or external file, then you will need to include it as a separate file with your installation, and have SU Ruby load it before attempting to load your script, so that your script will have access to it.

      That is all I have to offer though. If it is more complex than that, I am out of ideas,

      Chris

      Lately you've been tan, suspicious for the winter.
      All my Plugins I've written

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by 5 Oct 2009, 06:43

        @metasim said:

        (matching the 1.8.5 that appears to be in Sketchup currently)

        I thought it was 1.8.0 ...

        Thomas Thomassen β€” SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by 5 Oct 2009, 06:46

          Checked in SU7.1 just to be sure they haven't updated it:

          ` Object::RUBY_VERSION

          1.8.0`

          Thomas Thomassen β€” SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • RunnerPackR Offline
            RunnerPack
            last edited by 5 Oct 2009, 07:40

            I'm going to provide my "armchair CS major" version of what I think is going on. πŸ˜‰

            I've had some experience with SWIG and Ruby extensions and, from what I've read, the wrapper/extension has to be linked to the same libruby that was linked with the ruby runtime, i.e. the executable called "ruby" (or "ruby.exe" for the win32 version) in a stand-alone installation.

            In SketchUp's case, the environment is inside the SketchUp executable, and the libruby included (in my SU7.1/win32 install) is 'msvcrt-ruby18.dll'.

            So, what you need to do is find out how to link against a 1.8.0 version of the ruby library. It goes without saying that said library also has to be compiled for the same machine/OS as the one SU is using. Actually, the one extension I compiled for SU was linked against the 1.8.7 version of "msvcrt-ruby18.dll" and still worked (well, it didn't actually work, but that was because it also used OpenGL for graphics, but it didn't crash SU, at least).

            Ideally, you would link to the actual library included in the SU installation. I think on OSX it would be called "libruby-1.8.dylib" (or something like that).

            Of course, having absolutely no experience with OSX, I don't know how to deal with things like multiple processor architecture support and such, or even whether that applies to this situation πŸ˜†.

            A bit long-winded, but I hope it helps πŸ˜„

            You might have noticed... I'm a bit of a ferpectionist.

            1 Reply Last reply Reply Quote 0
            • M Offline
              metasim
              last edited by 5 Oct 2009, 13:25

              @thomthom said:

              Checked in SU7.1 just to be sure they haven't updated it:

              ` Object::RUBY_VERSION

              1.8.0`

              I should have been clear about versions:

              I'm running Sketchup 7.1 (7.1.4870) on MacOS 10.5.8. This is what I get from the ruby console:
              > Object::RUBY_VERSION 1.8.5

              1 Reply Last reply Reply Quote 0
              • J Offline
                Jim
                last edited by 5 Oct 2009, 13:29

                I thought SketchUp used the already installed Ruby on Macs, and ships with a .dll on Windows?

                What happens when a Mac user upgrades to Ruby 1.9? Do the differences between platforms continue to diverge when in fact they need to unite?

                Hi

                1 Reply Last reply Reply Quote 0
                • M Offline
                  metasim
                  last edited by 5 Oct 2009, 13:38

                  @runnerpack said:

                  ...
                  Ideally, you would link to the actual library included in the SU installation. I think on OSX it would be called "libruby-1.8.dylib" (or something like that).
                  ...
                  A bit long-winded, but I hope it helps πŸ˜„

                  Actually it helps quite a bit. Pointing out that the ruby runtime was "minimalist" is a good hint. On MacOS the libraries, resources, etc. are provided as "Framework" bundles. Normally a Framework bundle contains the header files and libraries, and older versions of Sketchup had the "minimalist" header files. Now even those are missing, leaving the Framework bundle as mostly empty directories with the exception of a single file called "Ruby", which is (confusingly) the shared library and not the interpreter (no idea why they leave the extension off in Frameworks).

                  So that's my long-winded way of saying that your arm-chair analysis gives me a coule things to try out πŸ˜„ Thanks!

                  Simeon

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by 5 Oct 2009, 13:41

                    @metasim said:

                    @thomthom said:

                    Checked in SU7.1 just to be sure they haven't updated it:

                    ` Object::RUBY_VERSION

                    1.8.0`

                    I should have been clear about versions:

                    I'm running Sketchup 7.1 (7.1.4870) on MacOS 10.5.8. This is what I get from the ruby console:
                    > Object::RUBY_VERSION 1.8.5

                    That's interesting...
                    I'm using SU7.1.4871 on PC

                    Wonder why the different platforms has different builds...

                    Thomas Thomassen β€” SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • M Offline
                      metasim
                      last edited by 5 Oct 2009, 13:47

                      @jim said:

                      I thought SketchUp used the already installed Ruby on Macs, and ships with a .dll on Windows?
                      ...

                      While Ruby is included in modern MacOS versions, applications can have their own versions (of most any library) in their application bundle. In this case it's "SketchUp.app/Contents/Frameworks/Ruby.framework". Compared to the system Ruby Framework, it's very sparse:

                      Sketchup.app/Contents/Frameworks

                      Ruby.framework
                      Ruby.framework/Resources
                      Ruby.framework/Ruby
                      Ruby.framework/Versions
                      Ruby.framework/Versions/A
                      Ruby.framework/Versions/A/Resources
                      Ruby.framework/Versions/A/Resources/English.lproj
                      Ruby.framework/Versions/A/Resources/English.lproj/InfoPlist.strings
                      Ruby.framework/Versions/A/Resources/Info.plist
                      Ruby.framework/Versions/A/Ruby
                      Ruby.framework/Versions/Current
                      
                      

                      /System/Library/Frameworks

                      Ruby.framework
                      Ruby.framework/Headers
                      Ruby.framework/Resources
                      Ruby.framework/Ruby
                      Ruby.framework/Versions
                      Ruby.framework/Versions/1.8
                      Ruby.framework/Versions/1.8/Headers
                      Ruby.framework/Versions/1.8/Headers/config.h
                      Ruby.framework/Versions/1.8/Headers/defines.h
                      Ruby.framework/Versions/1.8/Headers/digest.h
                      Ruby.framework/Versions/1.8/Headers/dl.h
                      Ruby.framework/Versions/1.8/Headers/dlconfig.h
                      Ruby.framework/Versions/1.8/Headers/dln.h
                      Ruby.framework/Versions/1.8/Headers/dtrace.h
                      Ruby.framework/Versions/1.8/Headers/env.h
                      Ruby.framework/Versions/1.8/Headers/intern.h
                      Ruby.framework/Versions/1.8/Headers/missing.h
                      Ruby.framework/Versions/1.8/Headers/node.h
                      Ruby.framework/Versions/1.8/Headers/re.h
                      Ruby.framework/Versions/1.8/Headers/regex.h
                      Ruby.framework/Versions/1.8/Headers/ruby.h
                      Ruby.framework/Versions/1.8/Headers/rubyio.h
                      Ruby.framework/Versions/1.8/Headers/rubysig.h
                      Ruby.framework/Versions/1.8/Headers/st.h
                      Ruby.framework/Versions/1.8/Headers/util.h
                      Ruby.framework/Versions/1.8/Headers/version.h
                      Ruby.framework/Versions/1.8/Resources
                      Ruby.framework/Versions/1.8/Resources/English.lproj
                      Ruby.framework/Versions/1.8/Resources/English.lproj/InfoPlist.strings
                      Ruby.framework/Versions/1.8/Resources/Info.plist
                      Ruby.framework/Versions/1.8/Resources/version.plist
                      Ruby.framework/Versions/1.8/Ruby
                      Ruby.framework/Versions/1.8/usr
                      Ruby.framework/Versions/1.8/usr/bin
                      Ruby.framework/Versions/1.8/usr/bin/erb
                      Ruby.framework/Versions/1.8/usr/bin/gem
                      Ruby.framework/Versions/1.8/usr/bin/gem_mirror
                      Ruby.framework/Versions/1.8/usr/bin/gemlock
                      Ruby.framework/Versions/1.8/usr/bin/gemri
                      Ruby.framework/Versions/1.8/usr/bin/gemwhich
                      Ruby.framework/Versions/1.8/usr/bin/irb
                      Ruby.framework/Versions/1.8/usr/bin/rdoc
                      Ruby.framework/Versions/1.8/usr/bin/ri
                      Ruby.framework/Versions/1.8/usr/bin/ruby
                      Ruby.framework/Versions/1.8/usr/bin/testrb
                      Ruby.framework/Versions/1.8/usr/bin/update_rubygems
                      Ruby.framework/Versions/1.8/usr/lib
                      Ruby.framework/Versions/1.8/usr/lib/libruby.1.dylib
                      Ruby.framework/Versions/1.8/usr/lib/libruby.dylib
                      Ruby.framework/Versions/1.8/usr/lib/ruby
                      Ruby.framework/Versions/1.8/usr/share
                      Ruby.framework/Versions/1.8/usr/share/ri
                      Ruby.framework/Versions/Current
                      ...
                      (continues for ~37,000 more lines)
                      
                      

                      The fact that Google doesn't include the header files that it used in its version of the ruby runtime makes it a little bit tricky to compile with Swig (and cmake, in my case); you kinda have to mix and match Framework components.

                      Simeon

                      1 Reply Last reply Reply Quote 0
                      • M Offline
                        metasim
                        last edited by 5 Oct 2009, 13:59

                        Success!

                        Forcing the linking of the shared library in Sketchup.app was the trick (can't just add it to the library search path).

                        For other cmake users, here's the CMakeLists.txt fragment that did the trick:

                        CMakeLists.txt

                        
                        ...
                        find_package(Ruby REQUIRED)
                        if(HAVE_SKETCHUP)
                            set(SKETCHUP "/Applications/Google\ SketchUp\ 7/SketchUp.app")
                            set(SKETCHUP_RUBY "${SKETCHUP}/Contents/Frameworks/Ruby.framework")
                            set(SWIG_RUBY_LIB "${SKETCHUP_RUBY}/Ruby")
                        else()    
                            set(SWIG_RUBY_LIB "${RUBY_LIBRARY}")
                        endif()    
                        
                        swig_add_module(${RUBY_MODULE_NAME} ruby "${INTERFACE_FILES}")
                        include_directories(${RUBY_INCLUDE_PATH})
                        swig_link_libraries(${RUBY_MODULE_NAME} "${MYEXTENSION_LIB}" "${SWIG_RUBY_LIB}") 
                        ...
                        
                        

                        Interestingly, when linking against this, MacOS is smart enough to encode the path to the Ruby library relative to the executable, so that if Sketchup.app is installed in a different location, it still works fine:

                        otool -L MyExtension.bundle

                        
                        	@executable_path/../Frameworks/Ruby.framework/Versions/A/Ruby (compatibility version 1.8.0, current version 1.8.5)
                        	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
                        	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
                        	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
                        
                        

                        I hope someone else finds this useful. I'm glad I don't have to resort to a client/server type implementation and associated headaches.

                        Thanks for all your help!

                        Simeon

                        1 Reply Last reply Reply Quote 0
                        • M Offline
                          MaistorKokir
                          last edited by 16 Apr 2012, 00:59

                          @metasim said:

                          Success!

                          Forcing the linking of the shared library in Sketchup.app was the trick (can't just add it to the library search path).

                          For other cmake users, here's the CMakeLists.txt fragment that did the trick:

                          CMakeLists.txt

                          
                          > ...
                          > find_package(Ruby REQUIRED)
                          > if(HAVE_SKETCHUP)
                          >     set(SKETCHUP "/Applications/Google\ SketchUp\ 7/SketchUp.app")
                          >     set(SKETCHUP_RUBY "${SKETCHUP}/Contents/Frameworks/Ruby.framework")
                          >     set(SWIG_RUBY_LIB "${SKETCHUP_RUBY}/Ruby")
                          > else()    
                          >     set(SWIG_RUBY_LIB "${RUBY_LIBRARY}")
                          > endif()    
                          > 
                          > swig_add_module(${RUBY_MODULE_NAME} ruby "${INTERFACE_FILES}")
                          > include_directories(${RUBY_INCLUDE_PATH})
                          > swig_link_libraries(${RUBY_MODULE_NAME} "${MYEXTENSION_LIB}" "${SWIG_RUBY_LIB}") 
                          > ...
                          > 
                          

                          Interestingly, when linking against this, MacOS is smart enough to encode the path to the Ruby library relative to the executable, so that if Sketchup.app is installed in a different location, it still works fine:

                          otool -L MyExtension.bundle

                          
                          > 	@executable_path/../Frameworks/Ruby.framework/Versions/A/Ruby (compatibility version 1.8.0, current version 1.8.5)
                          > 	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
                          > 	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
                          > 	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
                          > 
                          

                          I hope someone else finds this useful. I'm glad I don't have to resort to a client/server type implementation and associated headaches.

                          Thanks for all your help!

                          Simeon

                          Thx Simeon ... Someone else did find this useful πŸ˜„

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            DavidBluecame
                            last edited by 24 Mar 2017, 16:23

                            @metasim said:

                            Success!
                            [...]

                            I hope someone else finds this useful. I'm glad I don't have to resort to a client/server type implementation and associated headaches.
                            Simeon

                            Hello,

                            I've taken the time to register in SketchEducation just to be able to thank you for this excellent tip. Thanks to you I've been able to succeed after many headaches with my .bundle Swig/CMake generated Ruby/Sketchup extension files causing segfaults every time I used "require" to load them.

                            Linking against the Sketchup 2016 embedded Ruby library solved the problems and now I can use the extension!!

                            It was extremely useful. Thank you very much! πŸ˜„

                            1 Reply Last reply Reply Quote 0
                            • 1 / 1
                            • First post
                              Last post
                            Buy SketchPlus
                            Buy SUbD
                            Buy WrapR
                            Buy eBook
                            Buy Modelur
                            Buy Vertex Tools
                            Buy SketchCuisine
                            Buy FormFonts

                            Advertisement