lua使用C++的指針、引用、值、數組

在使用C++進行Lua擴展時,C++中豐富的參數接受、處理方式包括指針、引用、值傳遞、數組等,會使人疑問,這種函數在Lua中該怎樣調用。
一、指針、引用,假設是這樣一個demo,代碼如下

//demo.h
void foo(int & val);
void foo1(int* val);

這兩個函數的實現留在demo.cpp中,主要爲打印一些內容以區分彼此。他的.i文件如下

//demo.i
%module example
%{
#include "demo.h"
%}
%include "cpointer.i"
%pointer_functions(int, intp);
%include "demo.h"

這裏面的cpointer.i文件爲swig提供的庫文件,可以在swig的安裝目錄下的Lib中找到,執行這個例子
如果錯誤,可能是這個Lib路徑SWIG_LIB沒有加入到環境變量中。
%pointer_functions(type,name)將會爲Lua提供幾個接口函數,包括
1、type *new_name()
使用calloc創建type類型對象,並返回

2、type *copy_name(type value)
使用calloc創建type類型對象,並使用value進行初始化

3、type *delete_name(type *obj)
刪除一個type類型對象

4、void name_assign(type *obj, type value)
對type對象obj賦值

5、type name_value(type *obj)
返回type對象obj的值
(注:這裏說的對象是lua中的,在c++中可能是對象,也可能不是)
執行:swig -lua -c++ demo.i
生成的文件demo_wrap.cxx已經支持c++的指針和引用,在lua中調用的方式爲:

--test.lua
a=demo1.new_intp();
demo1.intp_assign(a,2);
demo1.foo(a);
demo1.foo1(a);
demo1.delete_intp(a);

上面的%pointer_functions(type,name)也可以使用%pointer_class(type,name)替換,
只是替換之後,swig生成的Lua接口就不是上面的幾個函數了,而是類似於類的結構,
%pointer_class(int,intp) 將生成

struct intp {
   intp();                            // Create pointer object
  ~intp();                            // Delete pointer object
   void assign(type value);           // Assign value
   type value();                      // Get value
   type *cast();                      // Cast the pointer to original type
   static intp *frompointer(type *);  // Create class wrapper from existing
                                      // pointer
}

此時使用Lua腳本的調用語句也將相應變化

--test2.lua
a=demo1.intp();
a:assign(2);
demo1.foo(a);
demo1.foo1(a);

由此可見,在Lua中指針和引用的使用實際上沒有區別,底層最後都會轉化爲指針後進行操作
二、數組

c++中經常會使用到數組,因此swig在生成Lua接口是也提供了對數組的支持,例子如下:

//demo1.h
void foo(double arr[]);
--demo1.i
%module demo1
%{
#include "demo1.h"
%}
%include "carrays.i"
%array_functions(double, doubleArray);

這裏的%include "carrays.i" 是指導入swig提供的庫,而%array_functions(type,name)
將會生成一組Lua接口提供調用:
1、type *new_name(int nelements)

2、type *delete_name(type *ary)

3、type name_getitem(type *ary, int index)
返回type的值 ary[index].

3、void name_setitem(type *ary, int index, type value)
給ary[index]賦值
同樣的,也有一個%array_class(type,name) 的操作可以生成類結構

struct name {
   name(int nelements);                  // Create an array
  ~name();                               // Delete array
   type getitem(int index);              // Return item
   void setitem(int index, type value);  // Set item
   type *cast();                         // Cast to original type
   static name *frompointer(type *);     // Create class wrapper from
                                         // existing pointer
};

其在Lua中的調用方式隨使用的語句的不同而不同,讀者可以根據生成的接口自己寫lua測試代碼測試。
需要注意的是這裏的兩組語句:%pointer_functions(type,name)%pointer_class(type,name) 、
%array_functions(type,name)%array_class(type,name)` 都不能用於char*和char**,否則
將是不安全、不負責任的。

參考文獻:1、http://www.swig.org/Doc3.0/SWIGDocumentation.html#Library_nn4
2、http://www.swig.org/Doc3.0/SWIGDocumentation.html#Library_carrays
3、http://blog.csdn.net/u010640235/article/details/52073130

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章