1. 程式人生 > >C++程式中嵌入Ruby腳本系統

C++程式中嵌入Ruby腳本系統

作者: 楊粼波
Email: 
tx7do#yahoo.com.cn

    突發奇想的想要把Ruby嵌入到C++的程式裡面去,想了於是就去做了.現在只在Windows下面測試通過,其他系統下,我還沒有試過,不過基本過程大差不差的.

需要準備些什麼?
    1.Ruby(http://www.ruby-lang.org/en/downloads/),去頁面中下載最新版本的Ruby 的安裝包;
    2.Swig(http://www.swig.org/download.html),去頁面中下載最新的安裝包.

什麼是Ruby?
    Ruby,一種為簡單快捷面向物件程式設計(面向物件程式設計)而創的指令碼語言,由日本人松本行弘(まつもとゆきひろ,英譯:Yukihiro Matsumoto,外號matz)開發,遵守GPL協議和Ruby License。Ruby的作者認為Ruby > (Smalltalk + Perl) / 2,表示Ruby是一個語法像Smalltalk一樣完全面向物件、指令碼執行、又有Perl強大的文書處理功能的程式語言。

什麼是SWIG?

    SWIG(Simplified Wrapper and Interface Generator)是個幫助使用C或者C++編寫的軟體能與其它各種高階程式語言進行嵌入聯接的開發工具。SWIG能應用於各種不同型別的語言包括常用指令碼編譯語言例如Perl, PHP, Python, Tcl, Ruby and PHP。
  簡單來說,主要用於匯出C/C++程式庫給指令碼語言使用的一個自動化工具.匯出的工作是非常機械化,而且繁複的.

編譯環境設定
    Ruby在Windows下:
    標頭檔案在$RUBY_HOME/lib/ruby/1.8/i386-mswin32;
    lib在$RUBY_HOME/lib,為msvcrt-ruby18.lib;
    dll在RUBY_HOME/bin,其實只有一個dll,就是:msvcrt-ruby18.dll.
    在這裡需要注意到的是,$RUBY_HOME/lib/ruby/1.8/i386-mswin32/config.h這個檔案對VC的版本做了限制:

#if _MSC_VER != 1200
#error MSC version unmatch
#endif     所以,如果VC不是這個版本的話,編譯是通不過的,對此問題,最簡單的辦法就是:將這三行程式碼註釋掉,就可以了.

C++直譯器包裹程式碼
標頭檔案

#ifndef __RubyInterpreter_H__
#define __RubyInterpreter_H__


#include 
<string>

typedef unsigned 
long    VALUE;
typedef std::
string        String;

typedef VALUE(
*staticValueMethod)(
);
typedef VALUE(
*ProtectedMethod)(VALUE);

class RubyInterpreter
{
public:
    RubyInterpreter();
    
virtual~RubyInterpreter();

public:
    
/// 初始化直譯器
void initializeInterpreter();

    
/// 終止直譯器
void finalizeInterpreter();

    
/// 設定
void setOutputFunction(staticValueMethod func);

    
/// 加入引用庫的搜尋路徑
void addSearchPath(const String& path);

public:
    
/// 執行語句
bool execute(const String& command);
    
    
/// 執行檔案
bool executeFile(String rubyfile);

private:
    
/// 記錄錯誤日誌
void logRubyErrors(const std::string& intro, int errorcode);
    
    
///
void loadProtected(ProtectedMethod func, VALUE args,
        
const std::string& msg, bool exitOnFail =false);

    
///
static VALUE loadDlls(VALUE);
}
;


#endif
原始檔

#include 
"StdAfx.h"
#include 
"RubyInterpreter.h"

#include 
"FixRubyHeaders.h"
#include 
<ruby.h>
#include 
"FixRubyHeaders.h"


RubyInterpreter::RubyInterpreter()
{

}


RubyInterpreter::
~RubyInterpreter()
{

}


void RubyInterpreter::initializeInterpreter()
{
#if defined(NT)
    
staticint dummyargc(0);
    
staticchar** vec;
    NtInitialize(
&dummyargc, &vec);
#endif

    
// 初始化Ruby
    ruby_init();

    
// 使用UTF8編碼
    execute( "$KCODE = 'u'" );

    
// addSearchPath();

    
// 初始化指令碼載入路徑
    ruby_init_loadpath();

    
// 設定安全級別
    rb_set_safe_level(0);

    
//
    ruby_script("ruby");

    
//loadProtected(&RubyInterpreter::loadDlls, 0, "Ruby error while loading dlls");
}


void RubyInterpreter::finalizeInterpreter()
{
    ruby_finalize();
}


void RubyInterpreter::setOutputFunction(staticValueMethod func)
{
    rb_defout 
= rb_str_new(""0);

    
// 定義一個虛擬類的方法
    rb_define_singleton_method(rb_defout, "write", func, 1);
}


void RubyInterpreter::addSearchPath(const String& path)
{
    ruby_incpush(path.c_str());
}


VALUE RubyInterpreter::loadDlls(VALUE val)
{
    String lib;

    
//
return rb_require(lib.c_str());
}


void RubyInterpreter::loadProtected(ProtectedMethod func,
                                    VALUE val, 
                                    
const std::string& msg, 
                                    
bool exitOnFail)
{
    
int error =0;
    rb_protect(func, val, 
&error);
    logRubyErrors(
"Ruby error while initializing", error);
}


void RubyInterpreter::logRubyErrors(const std::string& intro, int errorcode)
{
    
if (errorcode !=0)
    
{
        VALUE info 
= rb_inspect(ruby_errinfo);
        rb_backtrace();
        
if (intro.length() >0)
        
{
        }

    }

}


bool RubyInterpreter::execute(const String& command)
{
    
int status =-1;

    rb_eval_string_protect(command.c_str(), 
&status);

    logRubyErrors(
"", status);

    
if ( status )
    
{
        rb_eval_string_protect(
"print $!"&status);
        
returnfalse;
    }


    
returntrue;
}


bool RubyInterpreter::executeFile(String rubyfile)

相關推薦

C++程式嵌入Ruby系統

作者: 楊粼波Email: tx7do#yahoo.com.cn    突發奇想的想要把Ruby嵌入到C++的程式裡面去,想了於是就去做了.現在只在Windows下面測試通過,其他系統下,我還沒有試過,不過基本過程大差不差的.需要準備些什麼?    1.Ruby(http://www.ruby

使用Boost::Python在C++應用程式嵌入Python:第二部分

在第1部分中,我們瞭解瞭如何在C++應用程式中嵌入Python,包括從應用程式呼叫Python程式碼的幾種方法。雖然我之前承諾在第2部分中完整實現一個配置解析器,但我認為看一下錯誤解析會更有建設性。一旦我們有一個很好的方法來處理Python程式碼中的錯誤,我將在第3部分中

使用Boost::Python在C++應用程式嵌入Python:第一部分

在本系列教程的簡介中,我說了將Python程式碼整合到Granola程式碼庫中的動機。簡而言之,它可以使我使用Python語言和標準庫的好處來完成在C++中通常很痛苦或笨拙的任務。當然,底線是我不必移植任何已有的C++程式碼。 今天,我們看一下使用boost::pyth

Linux 下c++程式列印系統當前時間

    //方案一,將當前時間折算為秒級,再通過相應的時間換算即可     //此檔案必須是c++檔案     /*     #include<iostream>     #include<ctime>     using namespace std

《Linux作業系統分析》之使用庫函式API和C程式碼嵌入彙編程式碼兩種方式使用同一個系統呼叫

本篇文章分析的是使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫,來說明在Linux系統中,系統呼叫的實現機制。 相關知識 首先關於這篇文章會介紹一些用到的知識。 一、什麼是核心態,什麼又是使用者態。 核心態:在高執行級別下,程式碼可以執行特權指令,

Linux執行shell的4種方法

linux shell 這篇文章主要介紹了Linux中執行shell腳本的4種方法總結,即在Linux中運行shell腳本的4種方法,需要的朋友可以參考下。bash shell 腳本的方法有多種,現在作個小結。假設我們編寫好的shell腳本的文件名為hello.sh,文件位置在/root/bin目錄中

《shell系統監控-------郵件告警》

郵件告警 shell 系統監控 我與眾多同學一樣,在沒有學習shell編程之前是對shell編程是一頭霧水的,然而它能做什麽我也不知道,就是覺得能夠使用一個與別人不一樣的方式去管理系統。現在我慢慢的懂shell的重要性,為小型的機房裏面做一個小小的shell監控足夠,當然大型的機房不能使

C 語言調用python 函數

string 2.7 + - rsize 加載 -o func buffer ios 剛好幾個月前做過,C++ 函數裏面先加載python 腳本,再調用 裏面的 def 函數,我把代碼貼出來,你在main 函數裏面,調用getDataByScript 函數,另外相同目錄下放

Linux自動安裝

linux腳本自動安裝如何讓你的主機自動的完成安裝,自動的回答系統提出的問題,編寫自動安裝腳本即可實現,如下將詳細解釋自動腳本安裝方法。systemd-config-kickstart ##自動應答腳本制作工具安裝成功,在安裝過程中systemd-config-kickstart 將做出腳本應答進行選擇語言

傳奇版本自動穿背包的裝備

bre 自動 衣服 適用於 box body bsp ssa 裝備 傳奇版本自動穿背包中的裝備腳本 適用於傳奇一條龍開區功能:自動穿背包中的裝備,TakeOn 物品名稱 裝備位置裝備位置:0 = 衣服 1 = 武器 2 = 蠟燭 3 = 項鏈 4 = 頭盔 5 = 左手鐲

鏈接器——鏈接

進行 src 文件中 ima vpd 技術分享 所有 鏈接 可執行 鏈接腳本 鏈接器根據說明具體的原則完成具體的工作?答案是:鏈接腳本。 1鏈接腳本的意義 鏈接腳本用於描述鏈接器處理目標文件和庫文件的方式1.合並各個目標文件中的段2.重定位各個段的起始地址3.重定位各個符號

Modelsim使用TCL編寫do文件實現自動化仿真

簡單 ilo warning truct 語言 .com tps fpga 仿真 通常我們使用Modelsim進行仿真,是通過圖形界面點點點來進行操作,殊不知Modelsim完美支持TCL腳本語言及批處理命令do文件。簡單來說就是從你修改完代碼後到你重新編

shell執行python並接收其返回值的例子

erl 結果 port ria 需要 deb def ID pri 1.在shell腳本執行python腳本時,需要通過python腳本的返回值來判斷後面程序要執行的命令 例:有兩個py程序 hello.py 復制代碼代碼如下: def main(): pri

shell執行shell

執行 info 分享 $1 所在 結果 com echo 目錄 1、a.sh #!/bin/sh name="hello" ./b.sh $name 2、b.sh(這裏把b.sh與a.sh放在同一目錄下,便於演示) #!/bin/shecho "parameter

shell執行sql(mysql為例)

技術分享 src ins 註釋 ima 嘗試 方式 sql腳本 分享圖片 1、sql腳本(t.sql) insert into test.t value ("LH",88); 2、shell腳本(a.sh 為方便說明,a.sh與t.sql在同一目錄下) 說明:

簡單介紹linux的shell

-a sun 程序設計 set 每次 image line ans 交互 一、shell基本介紹 Shell就是一個命令行解釋器,它的作用是解釋執行用戶的命令,用戶輸入一條命令,Shell就解釋執行一條,這種方式稱為交互式。 Shell還有一種執行命令的方式稱為

使用CefSharp在.Net程式嵌入Chrome瀏覽器(四)——啟動優化

在實際使用過程中,發現有的客戶端會出現chrome載入網頁過慢問題,定位後發現很多是因為設定系統代理所致,此時可以通過如下啟動引數禁止系統代理。 {"proxy-auto-detect", "0"},{"no-proxy-server", "1"}, 另外一個小技巧是: 由於cef本

使用CefSharp在.Net程式嵌入Chrome瀏覽器(五)——Javascript互動

要在CEF中和網頁的JS進行互動,首先我們要通過設定啟用Javascrit整合功能。 CefSharpSettings.LegacyJavascriptBindingEnabled = true;   呼叫JavaScript: 簡單的呼叫JavaScript可以直接

正則表示式之C程式使用正則

POSIX規定了正則表示式的C語言庫函式,詳見regex(3)。我們已經學習了很多C語言庫函式的用法,讀者應該具備自己看懂man手冊的能力了。本章介紹了正則表示式在grep、sed、awk中的用法,學習要能夠舉一反三,請讀者根據regex(3)自己總結正則表示式在C語言中的用法,寫一些簡單的程式,例

使用CefSharp在.Net程式嵌入Chrome瀏覽器(六)——除錯

chrome強大的除錯功能令許多開發者愛不釋手,在使用cef的時候,我們也可以繼承這強大的開發者工具。 整合除錯: 我們可以使用如下函式直接使用整合在chrome裡的開發者工具 _chrome.ShowDevTools(); 這種方式下,類似chrome中按F12,直接打開了一個開發者工具視窗,