วันศุกร์ที่ 10 มิถุนายน พ.ศ. 2559

การใช้ swig ในการเชื่อม Ruby (Sketchup)กับ C++

SWIG เป็น opensource ที่ใช้สำหรับการเชื่อมภาษา ที่ต่างกัน เนื่องจากการพัฒนาระหว่าง programmer ระหว่างโครงการ และ โปรแกรมเก่า จะมีความแตกต่างภาษา และระยะเวลาในการพัฒนาต่างกัน เพื่อไม่ให้ลงทุนใหม่ จึงเป็นการที่ดีในการเชื่อมการเขียนโปรแกรมแบบ Painless ดีที่สุด ในการนี้ ต้องการเขียนโปรแกรม Dotnet เช้ากับ Ruby ของ Sketchup จะเป็นทางที่ง่ายกว่า การ Code ไปตรงๆ การเชื่อม Ruby
หลักการ ของ SWIG จะเป็น Code Generator โดยจะสร้าง C++ หรือ C โปรแกรม source เป็น Class Wrapper

     [Ruby,Python,PHP,Java..] <--- > Wrapper Class (c, c++) <---> [C#,Java,..]

โดยการทำงานสามารถเป็นการติดต่อแบบ 2 ทาง ได้

ในการใช้กับ Sketchup จำเป็นต้องรู้ว่า Ruby ที่ใช้อยู่ เป็น Version ใหน
ถ้าเป็น Sketchup 8 จะเป็น Ruby 1.8 ถ้าเป็น version 2014-2016 จะเป็น Ruby 2.0
Source ในการ Compile จะต่าง กัน
ตัวอย่างเช่น ต้องการเชื่อม Ruby กับ C++ Class โดยไม่ต้องทำ Interface อะไรเลย

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
};

class Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area(void);
  virtual double perimeter(void);
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area(void);
  virtual double perimeter(void);
};

ใน Ruby ต้องการ เขียน เข้าไป Access Class ของ C++ ตรงๆ


c = Example::Circle.new(10)
s = Example::Square.new(10)

print "\nA total of #{Example::Shape.nshapes} shapes were created\n"

# ----- Member data access -----
# Set the location of the object

# Notice how we can do this using functions specific to
# the 'Circle' class.
c.x = 20
c.y = 30

# Now use the same functions in the base class
s.x = -10
s.y = 5

print "\nHere is their current position:\n"
print "    Circle = (", c.x, ",", c.y, ")\n"
print "    Square = (", s.x, ",", s.y, ")\n"

# ----- Call some methods -----

print "\nHere are some properties of the shapes:\n"
for o in [c, s]
  print "    #{o}\n"
  print "        area      = ", o.area, "\n"
  print "        perimeter = ", o.perimeter, "\n"
end

การเชื่อมต่อ ระหว่างRuby กับ C++ใช้ Swig ทำได้โดยสร้าง Interface file


/* File : example.i */
%module example

%{
#include "example.h"
%}

/* Let's just grab the original header file here */
%include "example.h"


การเรียกใช้ Swig เพื่อสร้าง Class Wrapper
swig.exe -c++ -ruby sample.i

จะสร้าง file output -> sample_wrapper.cxx , .hxx ให้ นำไปใส่ใน Project Explorer
จะเป็น Interface file ให้ compile ด้วย Visual studio 2012,2013 

สำหรับ Header และ Library Download ตามนี้

https://github.com/thomthom/ruby-c-extension-examples/tree/VS2013/ThirdParty/include/ruby/2.0/win32

http://www.swig.org/download.html

ตัวอย่างการ Run  ใช้การ load Code ของ Ruby