日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

UCScript——C++集成脚本

發布時間:2023/12/10 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UCScript——C++集成脚本 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用UCScript作腳本,主要是因為它幾個特點很適合用于集成(腳本引擎體積小,占用資源少,運行快,跨平臺跨語言,與宿主語言交互方便),而且它的語法類C語言,不用去多學一門語言。在C++中集成UCScript腳本是輕而易舉的事。我們接下來用實例來說明,如何把UCScript腳本集成到你的程序中去。

1. 創建UCScript引擎

??? ucScript ucs; 或者 ucScript* ucs= new ucScript;

創建一個ucScript對象,就是創建一個UCScript腳本引擎。可以創建任意多個腳本引擎,甚至可以分布在不同的線程當中。

注意:指定合適的預定義,Windows用_UC_WIN,Linux用_UC_LINUX(即編譯參數-D_UC_LINUX)。如果以動態庫的形式使用腳本,還得指定_UC_IMPORT。

2. 執行腳本程序 你可以從緩沖區中裝載腳本,也可以直接解析文件:

??? const char * szCode="ret 1+2*3;";
??? ucScript ucs;
??? ucCalcVar vRet= ucs.Parse(szCode);
??? assert(vRet.value.iVal == 7);

如果你想對你的源代碼進行保護而不是赤裸裸的袒露在大家的眼前,或者提高腳本性能,你可以把腳本編譯成二進制中間碼。

3. 如何讓腳本調用C++的函數。比如讓腳本以string: get_peername(int: id)的形式調用我的C++代碼,代碼可以寫成:

UCSFUNC3(get_peername,CVT_STRING, "get peer name by peer id",
??????? CVT_INTEGER,"puid",
??????? CVT_STRING,"def=/"unknown/"",
??????? 1)
{
??? int puid;
? ? //? get?an integer value from the first parameter
??? ucAdaptCVT::cvt2out(params[0], puid);

????CPeer * p=CPeerMgr::Instance().GetPeer(puid);
????if(p) {
????????return p->m_PeerInfo.name;? //? return the string of name
????}
????const char * def="unknown";
????if(count>1) {
????????ucAdaptCVT::cvt2out(params[1], def);? //? get?default name specified by parameter
????}
????return def;
}

上面代碼用了UCSFUNC(xxx) 輔助宏,定義在ucScriptFunc.h頭文件。其中xxx表示腳本變量類型個數(即返回值和參數的個數)。上例的宏參數分別表示:

get_peername函數名字
CVT_STRING函數返回值的類型為string
函數的提示信息在腳本集成開發環境ucDev可以看到
CVT_INTEGER第一個參數,類型為integer
參數的提示信息用在ucDev
CVT_STRING第二個參數,類型string
參數提示信息用在ucDev
1有 1 個參數有默認值,即最后一個參數

腳本調用如下:

string: strName;

strName = get_peername(12);? //? Kevin's ID is 12, so strName = "Kevin"
strName = get_peername(-1);? //? none, strName = "unknown"
strName = get_peername(-1, "no user");? //? none,?strName = "no user"

最讓我激動的是,該腳本把非標準類型的變量全部當作object類型,也就是說任何C++類型都可以接受。下面例子演示如何傳遞和返回非基本類型的變量。

UCSFUNC2(get_parentwnd, CVT_OBJECT, "get a parent window",
???????CVT_OBJECT,"wnd",
??????? 0)
{
??? ucCalcVar vRet(CVT_OBJECT);
????CWnd * pWnd=NULL;
??? //? get?CWnd from?parameter
??? ucAdaptCVT::cvt2out(params[0], pWnd);

??? if(pWnd && ::IsWindow(pWnd->GetSafeHwnd()) )
??? {
??????? ucAdaptCVT::out2cvt(pWnd->GetParent(), vRet);
????}
??? return vRet;
}

4. 結束語

UCScript是一種面向集成的腳本語言,上面例子是針對C++語言,還支持的其他語言有C#(.Net),Java,Delphi,Visual Basic等等。腳本開發工具可以從http://www.ucscript.com/view_download.asp?id=3下載。初學者可以從http://www.ucscript.com/download.asp下載腳本用戶手冊。

(上文轉自http://blog.csdn.net/amken/article/details/1491877)


不同語言之間相互調用函數,這是很普遍的現象,尤其是多種語言并存開發的大項目。一般解決方案是,其中一種通過動態鏈接庫或者COM組件暴露接口,而另一種語言去調用。


腳本語言調用其它語言,則是通過支持庫或者腳本自身支持。就拿VBScript來說,可以通過實現IDispatch接口,腳本創建自動化對象來調用。各種腳本語言都有各自的方式來實現。UCScript是面向集成的腳本語言,這方面跟其它語言來比,更顯簡練和高效的優勢。下面分別從普通函數、類成員函數這兩方面介紹UCScript如何調用C++語言的函數。

1. 普通函數
在C++一提到函數調用,不得不提到的是調用約定(calling convention)。最常用的有__stdcall,__cdecl,__fastcall等幾種方式。


__stdcall是Windows API函數使用的規范,由被調用函數負責參數從堆棧移走,生成的代碼比__cdecl小。this指針壓入堆棧。以“?”標識函數名的開始,后跟函數名; 函數名后面以“@@YG”標識參數表的開始,后跟參數表; 參數表的第一項為該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前。


__cdecl調用約定是C/C++默認的調用規范,由調用函數負責參數從堆棧移走,有利于參數個數可變。this指針壓入堆棧。對于傳送參數的棧是由調用者來維護的(正因為如此,實現可變參數的函數只能使用該調用約定)。另外,在函數名修飾約定方面也有所不同。 __cdecl是C和C++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。


__fastcall規則同上面的__stdcall調用約定,它的主要特點就是快,因為它是通過寄存器來傳送參數的,即用ECX和EDX傳送前兩個參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧),在函數名修飾約定方面,它和前兩者均不同。UCScript不支持這種調用的函數。


__stdcall和__cdecl的最大區別就是用來傳遞參數的堆棧空間的清除。UCScript底層屏蔽這個差異,也就是說不管是哪一種方式,對UCScript都是一樣的。用戶不必關心這些細節,可以降低用戶使用復雜度。


int __cdecl strtoint(std::string str) {
printf("strtoint: str=%s\n", str.c_str());
return atol(str.c_str());
}


要讓腳本調用這個C語言的函數,只需如下的一行語句即可


BIND_UCSFUNC2(strtoint, strtoint, CVT_INTEGER, "convert string to int", (std::string*)CVT_OBJECT, "str");


下面分析上面各個參數的含義。


BIND_UCSFUNC2 該函數有2個腳本類別(Script Type),返回值和一個參數
strtoint 腳本可以調用到的函數名字,不必跟C++語言函數相同名字
strtoint C++語言的函數名字
CVT_INTEGER 函數返回值是Integer
"convert string to int" 函數說明,在ucDev編程可以看到該提示
(std::string*)CVT_OBJECT 參數是Object,并且轉換為std::string類型
"str" 參數說明,在ucDev編程可以看到該提示

2. 類成員函數
類成員函數可以分成兩類。一類是this指針通過ECX寄存器來傳遞;另一類是this指針通過參數傳遞。UCScript的輔助宏通過參數來區別這種區別。如下例:


class CMyClass {
public:
CMyClass() { m_id = 100; }
int GetId() {
printf("CMyClass::GetId, id=%d\n", m_id);
return m_id;
}
void SetId(int id) {
printf("CMyClass::SetId, id=%d\n", id); m_id = id;
}
int m_id;
};


要讓腳本調用到上面的GetId函數,只需下面語句


BIND_UCSFUNC_CM1(get_id, CMyClass, CMyClass::GetId, 1, CVT_INTEGER,"get id from a object");


上面的第4個參數指定this指針的傳遞方式:1表示標準方式,也就是this通過ECX寄存器傳遞;0是非標準方式,this通過參數傳遞。


當然,要調用這個函數還得傳入一個對象,這個對象可以是其它函數的返回值或者用BIND_UCS_GLOBALVAR綁定的全局對象。比如腳本的代碼可能如下:


object: obj;
// get obj by any way
... ...
int: id=get_id(obj);

3. 結束語
UCScript作為一種面向集成的腳本語言,在調用C++語言有自己獨特的方式。總結一下有如下特點:
可以傳遞任意C++類型,如上例的std::string類
封裝調用約定(calling convention)的差異
支持類成員函數調用
簡單方便,一行聲明語句即可

轉載于:https://www.cnblogs.com/zcwsmile/p/4027809.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的UCScript——C++集成脚本的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。