標籤:style class blog code http ext
Lua能夠調用C函數的能力將極大的提高Lua的可擴充性和可用性。
對於有些和作業系統相關的功能,或者是對效率要求較高的模組,我們全然能夠通過C函數來實現,之後再通過Lua調用指定的C函數。
對於那些可被Lua調用的C函數而言,其介面必須遵循Lua要求的形式,即typedef int (*lua_CFunction)(lua_State* L)。
簡單說明一下,該函數類型只包括一個表示Lua環境的指標作為其唯一的參數,實現者能夠通過該指標進一步擷取Lua代碼中實際傳入的參數。傳回值是整型,表示該C函數將返回給Lua代碼的傳回值數量,假設沒有傳回值,則return 0就可以。須要說明的是,C函數無法直接將真正的傳回值返回給Lua代碼,而是通過虛擬棧來傳遞Lua代碼和C函數之間的調用參數和傳回值的。
執行個體代碼:
// testlua.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <stdio.h>#include <string.h>#include <math.h>extern "C"{#include <lua.h>#include <lualib.h>#include <lauxlib.h>}//待Lua調用的C注冊函數static int add2(lua_State* L){//檢查棧中的參數是否合法,1表示Lua調用時的第一個參數(從左至右),依此類推。//假設Lua代碼在調用時傳遞的參數不為number,該函數將報錯並終止程式的執行。double op1 = luaL_checknumber(L,1);double op2 = luaL_checknumber(L,2);//將函數的結果壓入棧中。假設有多個傳回值,能夠在這裡多次壓入棧中。lua_pushnumber(L,op1 + op2);//傳回值用於提示該C函數的傳回值數量,即壓入棧中的傳回值數量。return 1;}//待Lua調用的C注冊函數。static int sub2(lua_State* L){double op1 = luaL_checknumber(L,1);double op2 = luaL_checknumber(L,2);lua_pushnumber(L,op1 - op2);return 1;}//待Lua調用的C注冊函數。static int l_sin (lua_State *L) {double d = lua_tonumber(L, 1); /* get argument */lua_pushnumber(L, sin(d)); /* push result */return 1; /* number of results */}int _tmain(int argc, _TCHAR* argv[]){lua_State *L = luaL_newstate();luaL_openlibs(L);//將指定的函數注冊為Lua的全域函數變數,當中第一個字串參數為Lua代碼//在調用C函數時使用的全域函數名,第二個參數為實際C函數的指標。lua_register(L, "add2", add2);lua_register(L, "sub2", sub2);lua_register(L, "l_sin", l_sin);//在注冊全然部的C函數之後,就可以在Lua的代碼塊中使用這些已經注冊的C函數了。luaL_dofile(L,"test.lua");//if (luaL_dostring(L,testfunc))// printf("Failed to invoke.\n");//const char *buf = "print(‘Hello World‘)";//luaL_dostring(L,buf);lua_close(L);return 0;}
test.lua
function show() print("helloworld") print(add2(1.0,2.0)) print(sub2(20.1,19)) print(l_sin(1))end show()
執行結果:
引用博文:http://www.cnblogs.com/stephen-liu74/archive/2012/07/23/2469902.html