在使用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