Nginx+lua 實現呼叫.so檔案

03ngnntds發表於2019-04-13

本文給大家分享的是Nginx結合lua 實現呼叫.so動態連結庫檔案的方法和示例,有需要的小夥伴可以參考下
最近在和智慧硬體部門一起,做一個室內定位的服務,該服務根據手機端傳過來的beacon裝置列表,根據一定的演算法計算出具體的商場,並將商場ID和beason裝置列表作為引數,呼叫.so檔案中的計算方法,得出位置資料(座標:x、y、z),返回給手機端。

因為服務對QPS要求比較高,並且都是純查詢操作,於是決定使用Nginx+lua+Redis的架構(該架構在公司內部已成主流,比較成熟)。下面我將對lua呼叫.so檔案的方式,做一下介紹。

lua呼叫.so檔案,主要有兩種方式:

1.Lua直接呼叫動態連結庫,具體可參考 技術分享 。
2.使用C寫一個Wrapper。

鑑於第一種方式需要引入第三方工具包,並且效率不高,所以我們採用第二種方式來實現。具體實現過程如下:

1.編寫業務程式碼,其中包括業務方法的封裝器。

static int lua_Locate( lua_State* L ) { long handle = lua_tonumber( L, 1 ); const char* beacon_rssi_json = lua_tostring( L, 2 ); vector<RSSI_INFO> rssi_info_vec; FingerprintLocationServer* p = (FingerprintLocationServer*)handle; ConvertJson2CppRSSI( beacon_rssi_json, rssi_info_vec ); double x; double y; float floor; p->UpdateBeaconSignalGetResult( rssi_info_vec, x, y, floor ); lua_pushnumber(L,x); lua_pushnumber(L,y); lua_pushnumber(L,floor); return 3; } static const struct luaL_Reg myLib[] = { {“lua_Locate”, lua_Locate}, {NULL, NULL} //陣列中最後一對必須是{NULL, NULL},用來表示結束 }; int luaopen_mLualib(lua_State *L) { luaL_register(L, “FPCalc”, myLib); return 1; // 把myLib表壓入了棧中,所以就需要返回1 }
其中,wapper函式的函式名有個命名規則,字首為luaopen,後面就是lua中require的字串,否則將會報類似於下面的異常:

lua entry thread aborted: runtime error: error loading module ‘mLualib’ from file ‘/var/wdd/wrs/webroot/intelligent_lua/mLualib.so’: /var/wdd/wrs/webroot/intelligent_lua/mLualib.so: undefined symbol: _Z13lua_tolstringP9lua_StateiPmstack traceback:coroutine 0: [C]: in function ‘require’ /var/wdd/wrs/webroot/intelligent_lua/location.lua:18: in function…
另外,如果是.cpp檔案,在luaopen_mylib一定要加 extern “C”, 否則匯出的函式會被重新命名,切記切記! 關於extern “C”,請參考 extern “C” 用法解析。

2.Nginx配置檔案中指定so包所在的資料夾。

lua_package_cpath ‘/var/wdd/wrs/webroot/intelligent_lua/?.so;;’;

注意,這裡有很多種配置方式,只要讓lua能找到so檔案即可,比如可以透過lua程式碼package.cpath來引入(參閱下面程式碼段)或者直接把so檔案複製lua環境變數指定的目錄裡等。
package.cpath = ‘/usr/local/lib/lua/5.1/?.so;’ --搜尋so模組

如果未指定cpath或者cpath中找不到so檔案,系統會報如下異常:

no file ‘./mLualib.lua’ no file ‘/usr/local/openresty/luajit/share/luajit-2.1.0-beta1/mLualib.lua’ no file ‘/usr/local/share/lua/5.1/mLualib.lua’ no file ‘/usr/local/share/lua/5.1/mLualib/init.lua’ no file ‘/usr/local/openresty/luajit/share/lua/5.1/mLualib.lua’ no file ‘/usr/local/openresty/luajit/share/lua/5.1/mLualib/init.lua’ no file ‘/usr/local/openresty/lualib/mLualib.so’ no file ‘./mLualib.so’ no file ‘/usr/local/lib/lua/5.1/mLualib.so’ no file ‘/usr/local/openresty/luajit/lib/lua/5.1/mLualib.so’ no file ‘/usr/local/lib/lua/5.1/loadall.so’ no file ‘/var/wdd/wrs/webroot/intelligent_lua/mLualib.so’

文章來源:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69911024/viewspace-2641242/,如需轉載,請註明出處,否則將追究法律責任。

相關文章