Ruby C++ extension crashes SketchUp
-
Hi everyone, I have a very weird problem to solve. I've programmed a C++ extension for a sketchup project. What I do :
-I compile it with extconf & make -> it works
-I test the source file on ruby console with irb and other commands -> it works
-I put require 'mytest' and include CallModule at the beginning of my ruby script and I put the source file into the plugin directory with the ruby script.
-I launch SketchUp and it crashes instantly.I made a lot of test and I'm sure SketchUp crashes because of my source file .so resulting of the compilation of my cpp file "mytest.cpp". I tried to remove the line "require 'my test" at the beginning of my ruby script and sure it crashes because of source file I put in the plugin directory. Moreover I tried to make a C version of my extension and I get the same problem.
Hope you can help me because I don't know what can I do. I'm on Windows XP Pro.
-
I had problems under OSX:
http://forums.sketchucation.com/viewtopic.php?f=180&t=28673&start=0
http://forums.sketchucation.com/viewtopic.php?f=180&t=33649Not sure if it's at all related, as it was working fine under Windows.
(Mind you, I'm very green at C Extensions - I only managed to compile mine because of help from TBD and AdamB.) -
Thanks for the quick reply. the problem is that i'm running it on Windows. The file you got after compiling the C extension is "Bundle" and mine a source, I don't know if there is a difference for SketchUp.
I saw your topic but I don't understand how you solved your problem? -
@breton_nerd said:
I saw your topic but I don't understand how you solved your problem?
By doing the modification AdamB suggested: http://forums.sketchucation.com/viewtopic.php?f=180&t=28673&start=0#p249370
@breton_nerd said:
The file you got after compiling the C extension is "Bundle" and mine a source, I don't know if there is a difference for SketchUp.
I have no idea, sorry.
-
Can you post a small, failing test case?
-
@breton_nerd said:
Hi everyone, I have a very weird problem to solve. I've programmed a C++ extension for a sketchup project. What I do :
-I compile it with extconf & make -> it works
-I test the source file on ruby console with irb and other commands -> it worksWhat Ruby version did you compile against ??
Sketchup cannot run anything in the v1.9.x Ruby trunk.
You need to compile with Ruby v1.8.6 PatchLevel 287 or higher (which is the interpreter distro'd with Sketchup 8.x)
@breton_nerd said:
I made a lot of test and I'm sure SketchUp crashes because of my source file .so resulting of the compilation of my cpp file "mytest.cpp". I tried to remove the line "require 'my test'" at the beginning of my ruby script...
-
Do not put spaces in filenames, perhaps especially source object files.
-
Always have your source object file all downcased characters. (Eliminates problems with the
require
method.)
The name of the C-side Init function must contain the exact so filename, with the same case: ie: Init_mytest
- Speed up the
require()
method's file search by specifying the .so file extension. (It will skip seaching for mytest.rb and mytest.rbw, mytest.dll, etc.)
@breton_nerd said:
... and sure it crashes because of source file I put in the plugin directory.
- Do not put .so files in the Plugins folder, put them in your extension subfolder.
plugins/breton_nerd/mytest/mytest.so* Users want control of what gets loaded, see the
[SketchupExtension](http://code.google.com/apis/sketchup/docs/ourdoc/sketchupextension.html)
class. Normally you have an extension registration script, plugins/mytest_ext.rb, in the plugins folder, and your plugin script is in a subfolder. In this example: plugins/breton_nerd/mytest/mytest_loader.rb@breton_nerd said:
-I put require 'mytest' and include CallModule at the beginning of my ruby script and I put the source file into the plugin directory with the ruby script.
-I launch SketchUp and it crashes instantly.- You should be calling:
require "breton_nerd/mytest/mytest.so"
-
Do not include (ie, Mix-In,) anything into
Object
. ONLY mixin modules into YOUR own modules or YOUR own custom classes, or by using theextend()
method to mix into an existing instance object. When you use theinclude()
method in code that is not wrapped in a module (or class) definition, you are trying to mix a module intoObject
. -
Besides a coder's (YOUR,) TopLevel module, ONLY Ruby Base Classes and Modules should be defined at the top level, which is actually
main
, a special instance of classObject
.
Your example above did not show that you are wrapping code within your toplevel module.
module BretonNerd module MyTest require( "breton_nerd/mytest/mytest.so" ) include( Mixin;;CallModule ) # # do stuff here with mixed in methods etc. # end end
- You can use a quick and dirty namespace called
Mixin
, to wrap "mixin modules" so they are separate from the Ruby Standard modules. (see this post where I show an example.)
But if you will be creating a special library of "mixin modules", to use with more than one of your plugins, then you should define your own
Mixin
namespace within your toplevel namespace module.module BretonNerd module Mixin # define mixin module CallModule here # from within the C/C++ source code. end end
P.S. - Your toplevel namespace module can be whatever unique (non-trademarked, not yet used by another plugin developer,) name you wish. I just used your SCF nickname as an example.
-
-
Just to be clear ...
It occurs to me that, if you are coming to Ruby from C or Python, you may be confused as to the use of the Ruby method
include()
.You do not need to "include" your compiled C-side Ruby module to use it in Ruby. (That's what the Ruby methods
require()
andload()
do.)Just
require()
it's so file, and if the return value istrue
, then your new module has been loaded, and it's ready to use. Such as calling it's methods, or accessing it's constants.Example, lets say you define a nested module in C/C++ named
BretonNerd::CallModule
, and compile it to mytest.so<span class="syntaxdefault">if require</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> </span><span class="syntaxstring">"breton_nerd/mytest/mytest.so"</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> BretonNerd</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">CallModule</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start_my_plugin</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault"> BretonNerd</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">CallModule</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">about_dialog</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault"> puts</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"My Test Module version is; #{BretonNerd;;CallModule;;VERSION}"</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">end</span>
In Ruby, the
include()
andextend()
methods, are for "mixing-in" features from a specially written module (called a "Mix-In" module,) into the current module or class, in special (and often confusing,) ways.Ruby does not have a "paste" method (although I wish it did,) that would just simply paste the contents of a module into the current namespace from where it was called. (I am forced to write a method of my own to do that.)
-
breton_nerd, i use this version of ruby http://rubyforge.org/frs/download.php/47082/ruby186-27_rc2.exe for compile C++ extension.
And I comment lines
//#if _MSC_VER != 1200
//#error MSC version unmatch
//#endif
in c:\Ruby186\lib\ruby\1.8\i386-mswin32\config.h
I had failed with other versions. What version of ruby you use? -
@exvion said:
breton_nerd, i use this version of ruby http://rubyforge.org/frs/download.php/47082/ruby186-27_rc2.exe for compile C++ extension.
And I comment lines
//#if _MSC_VER != 1200
//#error MSC version unmatch
//#endif
in c:\Ruby186\lib\ruby\1.8\i386-mswin32\config.h
I had failed with other versions. What version of ruby you use?Yes that is Ruby version 1.8.6-p287, the version of the interpreter that Google distro'd with Sketchup 8.x;
(The 27_rc2 refers to the One-Click Ruby Installer release package.)
Here is the Release Notes page link.
Advertisement