-อ.ธนะพันธ์ อินทรเกสร
ปัญหาของผู้ที่สร้างโปรแกรมบน Sketchup ต้องใช้ ruby ในการเขียนโปรแกรม
จะพบว่า การ Debug ยากมาก ใน Project ใหญ่แทบจะหา ไม่เจอเลยว่า โปรแกรม Bug อยู่ที่ใหน
เป็นคำถามที่นักศึกษาที่ทำ Project โปรแกรม ด้วย ruby sketchup กลัวกันมาก ผมไปศึกษาเพื่อที่ว่าจะได้ง่ายขึ้น
และอีกอย่างเป็นการนำ Library เช่น Database หรือ Graphic หลายอย่างที่พัฒนาบน C มาใช้
ได้โดยไม่ต้อง เขียนใหม่บน ruby
Ruby C Extension
ต้องเข้าใจก่อนว่า ruby ที่อยู่ใน Sketckup ไม่ได้เป็นภาษาเฉพาะของ
Sketchup คนเดียว แต่เป็นภาษาที่มีคนใช้ในโปรแกรมหลาย Application เช่น RubyOnRail
ใช้ในการทำ Web Server , หรือ Ruby สำหรับ DBMS ในการจัดการฐานข้อมูล เป็นต้น Ruby
พัฒนาแกนภาษาโดย
กลุ่ม Opensource
ซึ่งจะพัฒนาเรื่องภาษาเป็นหลัก สำหรับการต่อเชื่อมเข้ากับ
Application ต่างๆ จะเป็นเรื่องของโปรแกรมแต่ละคนไปทำกันเอง สำหรับ Sketckup จะใช้
โปรแกรม Ruby Version 1.8.6 เป็น core Language เหมือนกับทุกภาษา แก่นของภาษา ruby
พัฒนาบนภาษา C ดังนั้น ถ้าเขียน Application บนภาษา C ก็จะต่อกับ Ruby ได้
การต่อเชื่อมกับ ruby ใน Sketckup ใช้วิธีเดียวกับ การต่อกับ
RubyOnRail โดยการสร้างเป็น .so สำหรับบน MAC(OSX) และ .dll สำหรับ Windows และนำเข้าใช้คำสั่ง
require ‘ชื่อโปรแกรม’
มีบทความที่น่าจะช่วยได้มาก
และสำหรับ Sketckup
ลุยกันเลยดีกว่า
แล้วจะเริ่มเขียนโปรแกรมอย่างไร เลือก Windows จะสะดวกกว่า เพราะใช้
Visual Studio 2010 ในการพัฒนา
ให้ไป Download Visual Studio 2010 มาจาก www.microsoft.com ใช้ Standard C/C++ ก็พอเพราะฟรี
ต่อไป ต้องไป Download Ruby มากก่อน เลือก Version 1.8.6
และทำการ แตกโปรแกรมลงใน c:\ruby
ทีนี้ต้องใช้ Dos หรือ cmd ผู้ที่ไม่คุ้นเคย จะลำบากพอสมควร แต่ใช้ไม่กีคำสั่ง
เข้าไปที่ path ที่กำหนดเช่น
cd \ruby\ruby-rhg\win32
และเรียกคำสั่ง
configure.bat
และเรียก nmake ต่อ โปรแกรมจะ compile ruby ให้
ที่สำคัญโปรแกรมจะสร้าง msvcrt-ruby18.lib ที่จะเป็นตัวเชื่อมกับ
ruby sketckup ซึ่งต้องตรง version กับใน Sketckup
สร้างโปรแกรมตัวอย่าง
เปิด Visual Studio เลือกสร้าง New project เป็น win32
project และเลือกเป็น Empty ในชื่อ sx_hello คือไม่มี Source จากนั้น ให้ Add New
Item เป็น C source ชื่อ sxhelloworld.c และ Def ในชื่อ sx_hello.def
ตั้งค่า ใน Project property
General->Configuration Type
|
Dynamic Library (.dll)
|
C/C++->Additional Include Directories
|
"C:\ruby\ruby-rhg";"C:\ruby\ruby-rhg\win32"
|
C/C++->Command Line
|
-MD -Ot -Ox -W4
|
Linker->Output
|
C:/Program Files/Google/Google SketchUp
8/Plugins/sx_hello.dll
|
Linker->Additional Dependencies
|
msvcrt-ruby18.lib
|
เลือก Output ไปที Plugins ของ google จะ ใช้ Require ได้
Source ของ sxhelloworld.c
/////
Ruby Headers /////
#include <ruby.h>
/////
Global References ////
static VALUE g_TI_ExtTest; // module
/////
Ruby Extension Methods /////
static VALUE f_Hello( VALUE self )
{
return
rb_str_new2( "Hello SketchUp Work!!"
);
}
/////
Initializer /////
__declspec( dllexport ) void Init_sx_hello( void
)
{
//
define Module
g_TI_ExtTest =
rb_define_module( "THANAPHAN" );
//
Constants
//
> THANAPHAN::VERSION
rb_define_const(
g_TI_ExtTest, "VERSION",
rb_str_new2( "1.0" ) );
//
Methods
//
> THANAPHAN.hi
rb_define_module_function( g_TI_ExtTest, "hi",
(VALUE*)f_Hello, 0 );
}
|
และใน sx_hello.def
LIBRARY "sx_hello"
EXPORTS
Init_sx_hello
|
ทั้งใน Source C และ def ต้อง Export ในชื่อ Init_ชื่อไฟล์ ไม่นั้นจะ ใช้ ruby->require ไม่ได้
ทำการ compile ใน Visual studio ต้องจบด้วย 1 succeeded จึงจะได้ โปรแกรม
..\..\sxhelloworld.c(32)
: warning C4024: 'rb_define_module_function' : different types for formal and
actual parameter 3
Linking...
External build tool
process set to low priority...
Creating library C:/Program
Files/Google/Google SketchUp 8/Plugins/sx_hello.lib and object C:/Program
Files/Google/Google SketchUp 8/Plugins/sx_hello.exp
Embedding
manifest...
External build tool
process set to low priority...
External build tool
process set to low priority...
Build log was saved
at "file://c:\ruby\hello\sx_hello\sx_hello\Debug\BuildLog.htm"
sx_hello - 0
error(s), 8 warning(s)
========== Build: 1
succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
|
ทดลองใน Sketchup เปิด Ruby Console พิมพ์ ตัวหนังสือตามสีฟ้า
require "sx_hello"
true
THANAPHAN::VERSION
1.0
THANAPHAN.hi
Hello SketchUp Work!!
|
เมื่อ Require จะทำการ load sx_hello.dll เข้ามาในโปรแกรม โดย
ruby จะตอบกลับเป็น true THANAPHAN จะเป็นชื่อ
Module และประกอบด้วย constant VERSION และ โปรแกรมใต้ Module ชื่อ hi จะตอบกลับด้วย
Hello SketchUp Work!! ส่วนต่อของ Ruby Sketchup และ C ทำงานได้แล้ว
เรื่องที่น่าสนใจคือ C++ ได้หรือไม่ ไม่ยาก เพราะ Syntax ไม่ต่างกัน
แต่ถ้าเป็น C# ต้องทำ Class Wrapper ก่อน จึงจะ ต่อได้ ถ้ามีเวลาผมจะ ทดลองมาให้อ่านกัน
ในกรณี Debug โปรแกรม ก็ให้กดที่ปุ่ม Start Debugging ใน Visual Studio และเลือก โปรแกรม Sketchup.exe ใน Folder Sketckup ก็จะทำงาน ได้ เหมือนการ Debug ปรกติ
สำหรับ Sketup 2015,2016 การ Compile จะใช้ Rub 2.0.0 p648 ต้องเลือกให้ถูกว่าจะเป็น win32 หรือ x64 ที่ www.ruby-lang.org และเมื่อ compile แล้ว จะใช้ นามสกุลเป็น .so
ตอบลบจึงจะ load ได้
Header ของ ruby.h อาจจะใช้ ของ 1.8 ได้ แต่ Lib ต้องเปลี่ยนเป็นของ 2.0.0 นามสกุล ของ lib จะเป็น .a
ตอบลบอยากศึกษาเรื่องการเขียน Plugin ภาษา Ruby พอจะมีหนังสือแนะนำไหมครับ ขอบคุณมากครับ
ตอบลบกำลังจะฝึกอยู่เหมือนกันครับอาจารย์ เริ่มยังไงดีครับ
ตอบลบ