sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [Tutorial] SketchUp Ruby C Extension

    Scheduled Pinned Locked Moved Developers' Forum
    176 Posts 16 Posters 25.9k Views 16 Watching
    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.
    • C Offline
      chyn2000
      last edited by

      Hey guys,

      So, I got the ruby extension process to work, but I seem to be running into one little catch... multithreading.

      FYI: I'm using Pelle's C with the options TBD suggested in his SUExt example. I'm on a Win 7 (64 bit) system (though hopefully that won't matter).

      I'm trying to use _beginthread, but using TBD's settings, it seems I have an unresolved symbol '_beginthread'.

      Just to let you know, I am kind of new to multithreading and DLLs. I have created threaded applications, but never a threaded dll.

      Taking an example program that I have gotten to compile and run as a standalone app (pelle's C option multithreaded (lib)), I add the libs, includes and functions required to make it a ruby extension and it suddenly can't resolve _beginthread.

      A couple of modifications to TBD's project settings and I get it to compile and even be recognized by the irb. However, it seems the second the thread tries to run, the whole irb closes.

      The settings I modified to "get it to work" was:
      Runtime library from multithread (dll) to multithread (lib)
      and turn off "Omit default library in object files"

      Any ideas?

      Thanks,
      Reg

      
      // general Windows
      #pragma comment(lib, "kernel32.lib")
      #pragma comment(lib, "gdi32.lib")
      #pragma comment(lib, "user32.lib")
      #pragma comment(lib, "shell32.lib")
      #pragma comment(lib, "advapi32.lib")
      
      // Ruby
      #define HAVE_ISINF 1  // isinf macro redefinition workaround
      #pragma comment(lib, "msvcrt-ruby18.lib");
      
      // DLL
      #pragma comment(lib, "crt.lib");
      
      #include <stdio.h>
      #include <windows.h>
      #include <process.h>         // needed for _beginthread()
       
      // Ruby headers 
      #include "ruby.h"
      
      void  silly( void * );       // function prototype
      
      // De fining a space for information and references about the module to be stored internally
      VALUE KMRH = Qnil;
      
      int j = -1;
      
      // our function
      VALUE method_display_model(VALUE self, VALUE input)
      {
          // Our program's first thread starts in the main function.
          printf( "Now in the main function.\n" );
      
          // Let's now create our second thread and ask it to start
          // in the silly() function.
      //    _beginthread( silly, 0, (void*)12 );  //Commented out to see if the program would stay alive and it does
      
          // From here on there are two separate threads executing
          // our one program.
      
          // This main thread can call the silly() function if it wants to.
      	while(j != 0)
      	{
          	silly( (void*)j );
      		j--;
      	}
      
          Sleep( 10000 );
      
      	int i = NUM2INT(input);
      	return INT2NUM(i + 1);
      }
      
      // The initialization method for this module
      void Init_KMRH(void)
      {
      	KMRH = rb_define_class("KMRH", rb_cObject);
      	rb_define_method(KMRH, "display", method_display_model, 1);
      }
      
      
      void  silly( void *arg )
      {
      	int k = 10;
      	while(k-- != 0)
      	{
      //    	printf( "The silly() function was passed %d\n", (INT_PTR)arg );
          	printf( "The silly() function was passed %d\n", k );
      	}
      }
      
      
      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        That's way beyond me. I've not dealt with threading at all. But I'll be keeping an eye on this as it something I might want to do in the future.

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

        1 Reply Last reply Reply Quote 0
        • C Offline
          chyn2000
          last edited by

          So, I have to apologize for wasting your time...

          First thing I need to do (yet again) is RTFM.

          The answer to threading is incredibly simple:
          _beginthread( silly, 0, (void*)12 );

          becomes

          rb_thread_create( silly, (void*)12);

          found it on:
          http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html

          So, if you will excuse me, I need to go beat myself half to death...

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            You will not get any joy from using Ruby threads. They are "green" threads. It's just Ruby dividing up the tasks itself - not the system. So making a thread in Ruby will not prevent SU from freezing.

            Link Preview Image
            Parallelism is a Myth in Ruby - igvita.com

            favicon

            (www.igvita.com)

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

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              And Daniel Berger's win32-thread package that wraps native threads is still Alpha and unstable (AFAIK.)

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • J Offline
                jefftrull
                last edited by

                I'm on to the next challenge now... building for the 1.8.7-p334 version my colleagues prefer (better compatibility with certain gems). Unfortunately this one was built with with mingw, and my VS2010 build flow that worked for 1.8.6-p287 (mswin) is not successful here. I have the following results:

                1. build against 1.8.7-p334 built from source with VS2010: compile succeeds, load fails with missing dll msvcrt-ruby18-vc100 (or something like that). If I supply the dll, Sketchup crashes.
                2. build against 1.8.7-p334 one-click install (mingw): compile fails. Lots of warnings about win32.h and missing ruby API functions
                3. hybrid build pointing includes to mswin build of 1.8.7-p334, library from mingw one-click: link error

                I'm under the impression that because dll's use the C API it should be possible to load a VS2010-generated extension into a mingw-built Ruby. Is it a hopeless cause?

                Thanks,
                Jeff

                1 Reply Last reply Reply Quote 0
                • J Offline
                  jefftrull
                  last edited by

                  Today I made a startling discovery: the plugin I built under VS2010 against the 1.8.6-p287 mswin Ruby will load and run without changes in the 1.8.7-p334 mingw build. So the Ruby version and compiler both mismatch, and yet everything works. I'm dumbfounded but delighted, and my previous question is now moot.

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by

                    πŸ‘ πŸ˜„

                    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

                      @thomthom said:

                      Btw, does anyone know how one can make extconf.rb and make/nmake output their files to a given folder? I'd like to make it so that each platform outputs its generated files to separate directories.

                      Anyone know how to achieve this?

                      Making it so that when I build and compile under Windows everything is placed in a "win32" folder and "osx" when using OSX?
                      Or rather, to clarify, I know how to do conditionals - just don't know how to control where the generated files are output.

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

                      1 Reply Last reply Reply Quote 0
                      • Dan RathbunD Offline
                        Dan Rathbun
                        last edited by

                        and you are compiling from the commandline, not from within the Visual Studio GUI interface, correct ?

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • thomthomT Offline
                          thomthom
                          last edited by

                          Currently using nmake that comes with MS VS C++.

                          And I'm using a extconf.rb with mkfm to generate the makefile.

                          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

                            Is it possible to build an Ruby C Extension under Windows that doesn't require additional libraries? When using Visual C++ to build the extensions require the C++ runtime library.

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

                            1 Reply Last reply Reply Quote 0
                            • tbdT Offline
                              tbd
                              last edited by

                              yes. my old example did that. best is to check the DLL imports section to see what functions it requires

                              SketchUp Ruby Consultant | Podium 1.x developer
                              http://plugins.ro

                              1 Reply Last reply Reply Quote 0
                              • thomthomT Offline
                                thomthom
                                last edited by

                                @unknownuser said:

                                yes. my old example did that. best is to check the DLL imports section to see what functions it requires
                                Ah, the Pelles C project! Is it possible to use to to just compile the C source without creating a project? (just trying to find a solution without creating too many extra project files.)

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

                                1 Reply Last reply Reply Quote 0
                                • tbdT Offline
                                  tbd
                                  last edited by

                                  @unknownuser said:

                                  Is it possible to use to to just compile the C source without creating a project? (just trying to find a solution without creating too many extra project files

                                  the .ppj file is just a collection of commands. you can easily convert it to a .bat file if you dont want to have extra files (remember to create the .def file for the .dll link)

                                  SketchUp Ruby Consultant | Podium 1.x developer
                                  http://plugins.ro

                                  1 Reply Last reply Reply Quote 0
                                  • thomthomT Offline
                                    thomthom
                                    last edited by

                                    Do you remember the cause of the C:\ruby\src\ruby-1.8.6-p111\missing.h(71): error #1050: Redefinition of macro 'isinf'. error? And can you explain what your workaround actually do?

                                    Trying to set up a project myself so I actually understand this.

                                    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

                                      And why is the macro redefinition just a warning for this guy, but an error in Pelles C?
                                      https://github.com/barrie0482/rrdruby_win32_build/wiki

                                      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

                                        hm... there is an msvcrt-ruby18.dll in the SketchUp folder - can I make my Visual Studio C++ project rely on this instead? So when the C Extension loads under SketchUp Ruby the runtime is there - installed by SketchUp. ??

                                        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

                                          @unknownuser said:

                                          @unknownuser said:

                                          And can you explain what your workaround actually do?

                                          isinf is already defined in PellesC libraries so there is no need to include that file again.

                                          But I am not including it myself - it's an error that comes from the Ruby missing.h file... :S

                                          
                                          Building hello_world.obj.
                                          Use <stdlib.h> instead of non-standard <malloc.h>
                                          C;\ruby\src\ruby-1.8.6-p111\missing.h(71); error #1050; Redefinition of macro 'isinf'.
                                          *** Error code; 1 ***
                                          Done.
                                          
                                          

                                          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

                                            @unknownuser said:

                                            http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx - the DLL is already loaded by Sketchup so it will use that version.

                                            When compiling with Pelles C, right? Any way to make VC++'s nmake rely on the bundled SketchUp CRT instead of the VSC++ CRT? (splitting my quest into two projects here...)

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

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 3
                                            • 4
                                            • 5
                                            • 6
                                            • 7
                                            • 8
                                            • 9
                                            • 5 / 9
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement