程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++實現對lua訪問的封裝,lua訪問封裝

C++實現對lua訪問的封裝,lua訪問封裝

編輯:C++入門知識

C++實現對lua訪問的封裝,lua訪問封裝


這是一個幾年前寫的對lua的訪問封裝,當時的項目僅提供了最基本的lua訪問接口:調用lua函數,向lua注冊標准格式的C++函數.

本來我想引進luabind,但luabind相對又過於復雜,並不是所有功能都是我需要的,並且還要為此引入龐大boost.最終還是決定

按需求編寫一個簡單的封裝庫.

首先簡單列一下我的需求:

1)可以注冊任意類型的C++函數到lua中

2)可以方便的調用lua函數,方便的訪問lua中的表

3)可以訪問lua中創建的對象,調用lua對象提供的方法

4)注冊C++類型到lua,使lua可以訪問C++對象的字段,和函數

下面介紹一下提供的一些API:

1)call_luaFunction,用於方便的調用lua函數,使用格式如下:

int ret = call_luaFunction<int>("funname",L);

2)register_function,用於向lua注冊任意類型的C++函數,例如有如下函數:

static int showmsg(const char *msg)

{

  printf("%s\n",msg);

  return 0;

}

則可以這樣注冊,register_function(L,"show",showmsg);

3)register_class,register_property,register_member_function用於向lua注冊一個C++類型

4)luaObject,代表lua中的對象,可以通過成員函數CallMemberFunction,SetMemberValue,GetMemberValue

訪問lua對象的方法和成員變量

5)luatable,代表lua中的表

6)Interger64用以支持在lua中實現64位整型運算

這裡說明一下,我不想C++對象在lua中被創建,而只能在C++中創建再傳遞給lua(Interger64是個例外,因為它主要是在lua中被使用的類型),所以register_class

並沒有提供構造函數的注冊.

測試代碼:

  1 #include "luaWrapper.h"
  2 #include <stdio.h>
  3 
  4 static int userdata(lua_State *L)
  5 {
  6     int *a = (int*)lua_touserdata(L,-1);
  7     printf("a = %d\n",*a);
  8     return 0;
  9 }
 10 static int showmsg(const char *msg)
 11 {
 12     printf("%s\n",msg);
 13     return 0;
 14 }
 15 
 16 class testa
 17 {
 18 public:
 19     int vala;
 20     int valb[10];
 21 };
 22 
 23 class testd
 24 {
 25 public:
 26     virtual void testdf(){}
 27     int vald;
 28 };
 29 
 30 class testb : virtual public testa,virtual public testd
 31 {
 32 public:
 33     
 34     virtual void function()
 35     {
 36         printf("this is function\n");
 37     }
 38 
 39     int64_t valb;
 40     double  vald;
 41 };
 42 
 43 class testc : public testb
 44 {
 45 public:
 46     void function()
 47     {
 48         printf("this is testc\n");
 49     }
 50 
 51     void functionc()
 52     {
 53         printf("functionc\n");
 54     }
 55 };
 56 
 57 int main()
 58 {
 59     luaWrapper lw;
 60     lw.init();
 61     lw.load("start.lua");
 62     lua_State *L = *(&lw);
 63     //測試注冊任意C++函數
 64     register_function(L,"show",showmsg);
 65     
 66     //測試向lua注冊C++類
 67     register_class<testb>(L,"testb");
 68     register_property("valb",&testb::valb);
 69     register_property("vald",&testb::vald);
 70     register_member_function("func",&testb::function);
 71 
 72     register_class<testc,testb>(L,"testc");
 73     register_member_function("funcc",&testc::functionc);
 74 
 75     testc tc;
 76     tc.valb = 1000000000000000002;
 77     tc.vald = 10.0f;
 78     testb tb;
 79     tb.valb = 1000;
 80     call_luaFunction<void>("test1",L,&tc,(int64_t)1000000000000000001);
 81     printf("%lld\n",tc.valb);
 82     printf("%f\n",tc.vald);
 83     
 84     luatable ret = call_luaFunction<luatable>("test2",L);
 85     int i=0;
 86     printf("{");
 87     for(;i<ret.size();++i)
 88     {
 89         printf("%d,",any_cast<int>(ret[i]));
 90     }
 91     printf("}\n");
 92     
 93     lua_results<5> ret1 = call_luaFunction<lua_results<5>>("test4",L);
 94     printf("{");
 95     for(i=0;i<ret1._rets.size();++i)
 96     {
 97         printf("%d,",any_cast<int>(ret1._rets[i]));
 98     }
 99     printf("}\n");    
100     
101     luaObject ac = call_luaFunction<luaObject>("test3",L);
102     ac.CallMemberFunction<void>("show");
103     printf("balance:%d\n",ac.GetMemberValue<int>("balance"));
104     ac.SetMemberValue<int>("balance",1000);
105     printf("balance:%d\n",ac.GetMemberValue<int>("balance"));
106     luatable lt_in;
107     for(int i = 0; i < 5;++i)
108         lt_in.push_back(i);
109     call_luaFunction<void>("test5",L,lt_in);
110     
111     call_luaFunction<void>("test6",L,"this is string");    
112     
113     lt_in.clear();
114     lt_in.push_back((const char*)"hello1");
115     lt_in.push_back((const char*)"hello2");
116     lt_in.push_back((const char*)"hello3");
117     lt_in.push_back((const char*)"hello4");
118     lt_in.push_back((const char*)"hello5");
119     call_luaFunction<void>("test5",L,lt_in);
120     getchar();
121     return 0;
122 }
 1 Account = {
 2 balance = 10,
 3 names=0,
 4 }
 5     
 6 
 7 function Account:withdraw (v)
 8       self.balance = self.balance - v
 9 end
10     
11 function Account:new (o)
12   o = o or {}   
13   setmetatable(o, self)
14   self.__index = self
15   return o
16 end
17 
18 function Account:show()
19     print("this is account show")
20 end
21 
22 function Account:getBalance()
23     return self.balance
24 end
25 
26 function Account:setBalance(val)
27     self.balance = val
28 end
29 
30 function t(tb)
31     tb:func()
32 end
33 
34 function test1(tb,i)
35     t(tb)
36     show("hello world")
37     print(tb.valb)
38     tb.valb = i64:new(10000003) 
39     tb.vald = 1000.2
40     print(i)
41 end
42 
43 function test2()
44     return {1,2,3,4,5}
45 end
46 
47 function test3()
48     account = Account:new();
49     account.balance = 100
50     account.name = "sniperHW"
51     return account
52 end
53 
54 function test4()
55     return 1,2,3,4,5
56 end
57 
58 function test5(lt)
59     print(lt[1])
60     print(lt[2])
61     print(lt[3])
62     print(lt[4])
63     print(lt[5])
64 end
65 
66 function test6(str)
67     print(str)
68 end

 


跪答案:lua與C交互,lua文件放在哪個目錄下???

跟C放在同一個目錄下就好了
如果工程在編譯的話 放到工程文件夾裡
如果是編譯好了 要脫離編譯器運行了 就放到exe同目錄下就好
前提是你在調用lua文件的時候是直接使用文件名
如果有需要放目錄裡 路徑加上就好 反正是從當前目錄開始計算
 

lua不定參封裝

調用的時候
lua_pcall四個參數意義你都知道吧
第一個是堆棧
然後是參數個數
再然後返回值
最後錯誤處理函數

所以只要把lua_pcall(L, 2, 1, 0);改成lua_pcall(L, n, 1, 0);
通過控制變量n來控制就好了

再者 以後發代碼好好斷行 不然別人看的很辛苦
material_print = print
function funky_print (...)
for i=1, arg.n do
material_print("lua: " .. arg[i])
end
end
funky_print("aa","bb","cc")
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved