青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

流逝的時光
總有一天我們都會離去 email: zzxhang@gmail.com
posts - 21,comments - 111,trackbacks - 0

  續上篇文章http://m.shnenglu.com/zzxhang/archive/2009/03/13/76490.html,繼續說明LuckyScript作為一門腳本是如何與主程序交互的,到目前為止,我已基本實現了大部分我最初對這門腳本的設想,我想,很快我就可以將它發布出去了,也許本來是可以更快一點的,這段時間煩人的事太多,而且,工作也開始忙起來了,我所謂的業余時間已經越來越少,我想,是時候結束這個吉祥物的開發了。

1、調用主程序函數
所有提供給腳本調用的函數都必須滿足luckyScript主程序函數的原型定義,這個原型是typedef void (*Lucky_Host_Func)(RuntimeState*),比如如果我們想提供一個求和的函數給腳本定義,那么首先必須在主程序中這樣定義這個求和函數:

void add(RuntimeState* state)
RuntimeState保存了腳本運行時的所有狀態信息,腳本在調用這個主函數時會把所有參數值推棧保存,需要注意的是參數是從左到右先后入棧的,所以取出參數的順序是從右到左
 1void add(RuntimeState* state)
 2{
 3    //取出參數,右邊的參數先出棧
 4    int val2 = lucky_popValueAsInt(state);
 5    int val1 = lucky_popValueAsInt(state); 
 6//取出參數,右邊的參數先出棧
 7
 8    int sum = val1 + val2; 
 9
10     //把結果傳進腳本
11    lucky_setReturnValue(state,sum);
12}
最后調用lucky_setReturnValue把結果傳進腳本,在完成這么個函數的定義后,我們必須把它注冊給腳本
lucky_registerHostFunc(state,add,"add")
這樣在腳本中就可以使用這個函數了,另外如果這個主程序函數返回的是腳本中所沒有的類型(比如對象,當然必須先注冊給腳本),那么還必須指定第四個參數returnType說明返回的類型。

2、調用DLL函數
在腳本中,我們可以導入DLL,并使用其中函數,luckyScript提供了兩個命令__importdll,__importdllfunction用于在腳本中導入DLL函數,例如,我們可以建一個DLL工程,在里面添加下面代碼:
extern "C" __declspec(dllexport)
int add(int a,int b)
{
    
return a + b;
}
假設導出的DLL名為test.dl,那么在腳本中,我們可以這樣導入這個函數
1__importdll "test.dll"
2//給出函數的原型定義
3__importdllfunction int __cdecl add(int a,int b)
4
5func Main()
6{
7    var sum = add(2,4);
8}

函數的調用約定可以指定為__cdecl或者__stdcall,至于值的類型則包含這些:int ,float,double,int64, char,wchar,ptr(指針), str(字符串) ,void,如果是已經在腳本注冊過的對象類型,那么指定為ptr.

3.用戶數據
類似lua,luckyScript允許用戶往腳本添加自己的數據,在適當的時候,我們可以再取出這些數據,這個所謂"適當的時候"通常也就是腳本調用主程序函數的時候,我們得到事先添加進腳本的數據,然后再用它做一些我們自己的事情,對于用戶數據的操作,luckyScript提供了以下幾個API:

1LUCKY_API void* lucky_addUserData(size_t size);
2
3    LUCKY_API int lucky_getLastUserDataIndex();
4
5    LUCKY_API void* lucky_getUserData(int index);
6
7    LUCKY_API void lucky_clearAddedUserData();
這幾個函數,恩,老實說,用法有點別扭,需要具體點說明,先看下面的代碼:
 1struct TestData
 2{
 3    int val;
 4}
;
 5
 6void doSomething(RuntimeState* state)
 7{
 8    TestData* d = (TestData*)lucky_popValueAsUserData(state);
 9    const char* str = lucky_popValueAsString(state);
10    print("%s: %d",str,d->val)
11}

12
13void TestFunc()
14{
15    TestData t;
16    t.val = 4;
17
18    lucky_initScript();
19
20    void* data = lucky_addUserData(sizeof(TestData));
21    memcpy(data,&t,sizeof(TestData));
22    
23    //得到索引
24    int index = lucky_getLastUserDataIndex();
25    
26    lucky_registerGlobalHostFunc(state,doSomething,"doSomething");
27    
28    //清空
29    lucky_clearAddedUserData();
30
31    //取出userData
32    TestData* t2 = (TestData*)lucky_getUserData(index);  
33
34    print("value(in TestFunc): %d",t2->val);
35
36    lucky_doString("doSomething(\"value(in doSomething): \")");
37
38    lucky_exitScript();
39}
 
40
41

在某個地方調用這個TestFunc,一切順利的話,應該會輸出"value(in TestFunc): 4 value(in doSomething): 4",但我并不確定,以上及以下的代碼都是我隨手打的,只用我的眼睛編譯過....如果你認真看完了上面的代碼,那么我想對這幾個函數的用法你應該都已經了解了,唯一需要解釋的是23-30行之間的代碼:為了更緊密地與主程序結合,當lucky_registerGlobalHostFunc或lucky_registerHostFunc被調用的時候,在內部,腳本引擎會把從上一次調用或還沒調用lucky_clearAddedUserData到現在為止所添加進去的用戶數據跟lucky_registerGlobalFunc所注冊的主程序函數綁定,當我們在腳本中調用這個主程序函數時,這些用戶數據就會被當作參數一樣壓棧,這樣,在主程序函數中,我們就可以調用lucky_popValueAsUserData取出這些數據,取出數據的順序跟添加的順序相反,也就是說,最后添加的用戶數據會被放在棧頂。利用這個特性,我們可以對luckyScript進行高層的封裝,使之可以更方便地注冊C++的類跟函數,在下一篇文章中,我會向你展示這個特性是如何被利用的。

4.主程序對象
  前面已經多次提到關于主程序對象的注冊,luckyScript允許用戶往腳本添加自己的對象類型,但不得不說,這個過程是有點小麻煩的,luckyScrip采用一套預定義的規定來進行主程序對象數據與腳本間的通信,在腳本中,所有主程序對象的操作,包括構造,析構,成員調用等都是由一些預定義命名規范的主程序函數來完成的,當一個主程序對象在腳本中構造時,與此對象類型同名的主程序函數將會被調用,當調用主程序對象的方法時,腳本將會采用className + memberFuncName的命名方式來call主程序函數,具體的命名規范如下所示:
構造函數:與類型名同名
析構函數:下劃線 + 類型名
調用成員函數:類型名 + 下劃線  +  成員函數名
操作符重載:類型名 +  下劃線 + Overide + 下劃線  +  操作符英文符號(如 '+' 為 Add)
成員變量存:類型名 + 下劃線 + set + 下劃線 + 成員變量名
成員變量取:類型名 + 下劃線 + get + 下劃線 +  成員變量名 

接下來用一個完整的例子代碼進一步說明主程序對象的注冊方法

 1class TestObj
 2{
 3public:
 4    TestObj()
 5    {
 6    
 7    }

 8
 9    ~TestObj()
10    {
11
12    }

13
14    void operator = (const TestObj& otherObj)
15    {
16        val = otherObj.val;
17    }

18
19    void doSomething()
20    {
21
22    }

23
24    int val;
25}
;
26
27void TestObjConstructor(RuntimeState* state)
28{
29    void* data = lucky_popValueAsUserData(state);
30
31    new(data) TestObj();
32}

33
34void TestObjDesConstructor(RuntimeState* state)
35{
36    TestObj* obj = (TestObj*)lucky_popValueAsUserData(state);
37
38    obj->~TestObj();
39}

40
41void TestObjSetVal(RuntimeState* state)
42{
43    TestObj* obj = (TestObj*)lucky_popValueAsUserData(state);
44
45    int setVal = lucky_popValueAsInt(state);
46    
47    obj->val = setVal;
48}

49
50void TestObjGetVal(RuntimeState* state)
51{
52    TestObj* obj = (TestObj*)lucky_popValueAsUserData(state);
53    
54    lucky_setReturnValue(state,obj->val);
55}

56
57void TestObjDoSomethingFunc(RuntimeState* state)
58{
59    TestObj* obj = (TestObj*)lucky_popValueAsUserData(state);
60    
61    obj->doSomething();
62}

63
64void TestObjOverideAssign(RuntimeState* state)
65{
66    TestObj* otherObj = (TestObj*)lucky_popValueAsUserData(state);
67    TestObj* obj = (TestObj*)lucky_popValueAsUserData(state);
68    
69    (*obj) = (*otherObj);
70}

71
72int main()
73{
74    lucky_initScript();
75
76    lucky_registerHostClass("TestObj",sizeof(TestObj));
           //構造函數處理回調函數命名規范:類型名
           lucky_registerGlobalHostFunc(TestObjConstructor,"Test");
          //析構函數處理回調函數命名規范:下劃線 + 類型名
           lucky_registerGlobalHostFunc(TestObjDesConstructor,"_Test");
77    lucky_addHostMemberFunc("TestObj","doSomething");
78    //成員函數處理回調函數命名規范:類型名 + 下劃線 + 成員函數名
79    lucky_registerGlobalHostFunc(TestObjDoSomethingFunc,"TestObj_doSomething");
80
81    lucky_addHostMemberVal("TestObj","val");
82    //成員變量處理回調函數命名規范:類型名 + 下劃線 + set/get + 下劃線 + 成員函數名
83    lucky_registerGlobalHostFunc(TestObjSetVal,"TestObj_set_val");
84    lucky_registerGlobalHostFunc(TestObjGetVal,"TestObj_get_val");
85
86    //操作符重載處理回調函數命名規范:類型名 + 下劃線 + Overide + 下劃線 + 操作符英文符號
87    lucky_registerGlobalHostFunc(TestObjOverideAssign,"TestObj_Overide_Assign");
88
89   lucky_doString("var t = new TestObj();\
90                   var t2 = new TestObj();\
91                   t.doSomething();\
92                   t.val = 3;\
93                   t2.val = t.val + 1;\
94                   t = t2;");
95
96   lucky_exitScript();
97}
  同樣,我不能保證上面代碼的正確性,我甚至沒有檢查過,但用它來說明問題已經足夠

5.調用腳本函數
腳本中能引用主程序的方法對象,主程序當然也可以用腳本的一些東西,luckyScript直接提供了API用于調用腳本函數:
LUCKY_API void lucky_callFunc(RuntimeState* state,const char* funcName,int paramNum);
LUCKY_API 
void lucky_callFunc(RuntimeState* state,const char* funcName,char** paramsTypeName,int paramNum);
需要說明下的是第二個API,假如你想調用的API包含主程序對象類型的話,那么還必須把所有參數的類型名傳進來,順序是從左到右,還有,兩個API都必須提供參數個數.....你要問為什么會這么麻煩,我會告訴你,一切都源于那個該死的所謂泛化特性,調用同一函數,提供不同的參數列表會編譯為不同的函數,當然函數名也會是不一樣的,so,我得根據參數類型的情況具體處理。

6.腳本對象
在這一塊我只提供了主程序對腳本全局變量的訪問
 1LUCKY_API int lucky_getGlobalIdentValAsInt(RuntimeState* state,const char* identName);
 2
 3LUCKY_API float lucky_getGlobalIdentValAsFloat(RuntimeState* state,const char* identName);
 4
 5LUCKY_API const char* lucky_getGlobalIdentValAsString(RuntimeState* state,const char* identName);
 6
 7LUCKY_API void* lucky_getGlobalIdentValAsUserData(RuntimeState* state,const char* identName);
 8
 9LUCKY_API void lucky_setGlobalIdentVal(RuntimeState* state,const char* identName,int val);
10
11LUCKY_API void lucky_setGlobalIdentVal(RuntimeState* state,const char* identName,float val);
12
13LUCKY_API void lucky_setGlobalIdentVal(RuntimeState* state,const char* identName,const char* val);
14
15LUCKY_API void lucky_setGlobalIdentVal(RuntimeState* state,const char* identName,void* val,const char* freeFuncName = "Null",size_t size = 0);
在最后一個API中,假設你提供的是主程序對象而又不打算在主程序中手動釋放它的話,那么還必須提供此對象的釋放主函數


可以看到,使用上面的介紹的方法來進行主程序跟luckyScript腳本的交互的話還是有諸多不方便的,因為這個原因,我已經為luckyScript實現了一個c++封裝庫,使用這個封裝庫可以方便的實現C++跟腳本間數據的通信,隱去一切瑣碎的細節,在下篇文章中,我會詳細介紹這個封裝庫。
posted on 2009-04-16 15:57 清風 閱讀(1351) 評論(1)  編輯 收藏 引用 所屬分類: LuckyScript

FeedBack:
# re: LuckyScript與主程序的交互
2009-04-18 10:30 | 陳梓瀚(vczh)
我現在調用dll的方法是吧整個腳本都弄成機器碼,然后在里面調……  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99这里只有久久精品视频| 一区二区三区国产精品| 久久日韩粉嫩一区二区三区| 亚洲一区二区成人在线观看| 亚洲精品在线视频观看| 亚洲欧洲日本国产| 亚洲高清视频一区| 亚洲人成网在线播放| 亚洲人www| 一区二区av| 宅男噜噜噜66国产日韩在线观看| 一区二区三区 在线观看视频| 99riav1国产精品视频| 洋洋av久久久久久久一区| 在线一区二区三区四区五区| 久久久亚洲成人| 久久香蕉国产线看观看av| 巨胸喷奶水www久久久免费动漫| 久久蜜桃资源一区二区老牛| 欧美国产极速在线| 日韩一二三区视频| 欧美一区深夜视频| 欧美激情1区2区3区| 欧美揉bbbbb揉bbbbb| 国产亚洲精品美女| 亚洲日本aⅴ片在线观看香蕉| 亚洲精品欧美精品| 欧美中文字幕在线| 亚洲欧洲精品一区二区精品久久久| 日韩一级成人av| 久久国产欧美日韩精品| 欧美国产先锋| 国产色视频一区| 一区二区三区欧美亚洲| 久久久噜噜噜久噜久久| 亚洲人成在线观看| 欧美一区二区成人| 欧美日韩精品欧美日韩精品 | 欧美一区二区三区免费看 | 亚洲精品日产精品乱码不卡| 性做久久久久久久免费看| 欧美成人免费小视频| 亚洲一区久久| 欧美体内谢she精2性欧美| 亚洲国产天堂久久国产91| 欧美中文在线观看| 一区二区三区视频免费在线观看 | 亚洲国产欧美在线| 久久精品中文| 亚洲欧美日韩中文视频| 欧美日韩国产综合新一区| 在线看无码的免费网站| 久久精品国产精品亚洲| 亚洲免费在线观看视频| 国产精品久久久久久久电影| 中国亚洲黄色| 一区二区国产精品| 国产精品裸体一区二区三区| 亚洲网友自拍| 亚洲视频1区2区| 国产精品日韩二区| 欧美一级大片在线观看| 亚洲欧美激情在线视频| 亚洲国产综合视频在线观看| 久久字幕精品一区| 国产精品啊v在线| 亚洲一区二区三区乱码aⅴ| 一本色道久久综合亚洲精品小说 | 欧美 日韩 国产精品免费观看| 亚洲一区激情| 国产精品日日摸夜夜添夜夜av | 久久免费精品日本久久中文字幕| 欧美一区二区啪啪| 在线欧美电影| 亚洲精品欧美日韩| 国产精品久久久久久久免费软件| 亚洲欧美伊人| 午夜精品在线| 亚洲高清资源综合久久精品| 91久久国产综合久久| 欧美特黄一级| 久久精品一二三区| 美脚丝袜一区二区三区在线观看| 在线观看日韩av先锋影音电影院| 美女图片一区二区| 欧美日韩黄视频| 欧美一区二区三区婷婷月色| 午夜影院日韩| 99在线|亚洲一区二区| 夜夜夜精品看看| 国产一区二区三区视频在线观看| 欧美高清hd18日本| 国产精品成人观看视频国产奇米| 久久国产欧美日韩精品| 欧美成在线观看| 久久精品国产欧美激情| 欧美国产综合视频| 欧美在线精品一区| 欧美国产先锋| 久久精品在线免费观看| 欧美激情视频一区二区三区不卡| 亚洲一区二区日本| 免费中文日韩| 欧美在线资源| 欧美小视频在线| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美自拍偷拍午夜视频| 久久综合网色—综合色88| 亚洲一区二区三区视频| 久久夜色精品| 欧美在线看片| 欧美视频在线视频| 免费在线亚洲| 国产自产在线视频一区| 亚洲特级片在线| 日韩一区二区精品视频| 久久久久国产精品人| 亚洲国产精品一区二区尤物区| 性一交一乱一区二区洋洋av| 亚洲破处大片| 香蕉久久夜色| 亚洲女人天堂成人av在线| 久久亚洲春色中文字幕| 久久福利精品| 国产精品国产三级国产aⅴ浪潮 | 老司机一区二区| 国产伦一区二区三区色一情| 欧美成人免费在线| 精品av久久久久电影| 欧美一级大片在线观看| 亚洲午夜精品一区二区三区他趣| 欧美承认网站| 欧美激情视频在线播放 | 亚洲欧美一区二区三区极速播放| 欧美激情视频一区二区三区免费 | 免费永久网站黄欧美| 黄色成人在线| 欧美一站二站| 久久成人羞羞网站| 国产综合婷婷| 久久久久久网站| 欧美成人一品| 在线观看日韩av| 久热精品视频在线免费观看| 奶水喷射视频一区| 亚洲高清一区二| 欧美精品久久99久久在免费线| 亚洲日本黄色| 亚洲视频www| 国产一区二区高清| 久久久久久亚洲精品不卡4k岛国| 噜噜噜噜噜久久久久久91| 在线观看视频欧美| 欧美高清视频| 亚洲视频每日更新| 久久久久久久999| 亚洲国产欧美在线| 欧美日本在线看| 亚洲先锋成人| 久久精品日产第一区二区三区| 国产一区二区三区在线观看免费视频| 欧美在线观看一区二区| 欧美xxxx在线观看| 国产精品99久久久久久久久| 国产精品日韩欧美综合 | 国产精品免费在线| 亚洲欧美日韩在线一区| 久久影视三级福利片| 亚洲国产精品久久久久久女王| 欧美精品一区二区三区在线播放| 亚洲一区二区三区成人在线视频精品 | 香蕉成人久久| 国产日韩精品在线播放| 欧美成人免费网| 久久野战av| 欧美精品www在线观看| 一区二区日韩欧美| 久久午夜色播影院免费高清| 亚洲黄色在线视频| 国产精品久久久久久久久久久久久 | 久久久久国产一区二区三区四区| 在线观看91精品国产入口| 欧美日韩国产综合新一区| 欧美一区二区三区四区在线| 亚洲国产欧洲综合997久久| 亚洲欧美一区二区三区久久 | 免费看亚洲片| 亚洲一区二区高清视频| 伊人久久亚洲热| 国产精品久久久久国产精品日日| 久久精品免视看| 99这里只有精品| 亚洲成色777777女色窝| 亚洲欧美日韩在线一区| 亚洲精品美女免费| …久久精品99久久香蕉国产 | 久久躁日日躁aaaaxxxx| 亚洲免费综合| 在线一区二区三区四区五区| 亚洲国产精品成人|