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