Luaは長い間使用されてきましたが、フレームワークの理由から、今日はLuaがsoライブラリを呼び出す方法について説明します。
私はそれをしないかどうか本当にわかりません。それをするのは素晴らしいことです。インターネット上の非常に多くの記事、基本的にあなたは私をコピーします、私はあなたをコピーします。エラーは同じであり、検証は検証されていません。。。
最初に私の環境、Ubuntu 18.04、lua5.3を宣言します
1.コンセプトサプリメント、LuaとCは仮想スタックを介して相互作用しますが、これはなぜですか?
CとLua間の通信の重要な内容は、仮想スタックです。ほとんどすべての呼び出しはスタック上の値を操作することであり、CとLua間のすべてのデータ交換もこのスタックを介して行われます。さらに、スタックを使用して一時変数を格納することもできます。Luaと通信するすべてのC関数には、Luaによって管理される独自の仮想スタックがあります。
スタックを使用すると、CとLuaの間の2つの不整合が解決されます。まず、Luaは自動的にガベージコレクションを実行しますが、Cはストレージユニットの明示的な割り当てを必要とするため、2つの間に矛盾が生じます。次に、Luaの動的タイプとCの静的タイプの間の不整合によって引き起こされる混乱。
2. Cでメソッドを呼び出すには、Cをダイナミックライブラリにコンパイルする必要があります。私はLinuxを使用しているため、.soであり、コードは次のとおりです。
c_so.cpp
extern "C" {
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
//自定义函数
static int my_add(lua_State *L)
{
int x = lua_tonumber(L,1); //第一个参数,转换为数字
int y = lua_tonumber(L,2); //第二个参数,转换为数字
int sum = x + y;
lua_pushnumber(L, sum); //将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
return 1; //返回sum计算结果
}
static int showstr(lua_State *L)
{
//从lua中传入的第一个参数
const char *str = lua_tostring (L, 1);
printf ("c program str = %s\n", str);
return 0;
}
/* 需要一个"luaL_Reg"类型的结构体,其中每一个元素对应一个提供给Lua的函数。
* 每一个元素中包含此函数在Lua中的名字,以及该函数在C库中的函数指针。
* 最后一个元素为“哨兵元素”(两个"NULL"),用于告诉Lua没有其他的函数需要注册。
*/
static luaL_Reg funclist[] =
{
{"add", my_add}, //my_add()函数,lua中访问时使用名称为add
{"show", showstr}, //showstr()函数,lua中访问时使用名称为show
{NULL, NULL}, //最后必须有这个
};
/* 此函数为C库中的“特殊函数”。
* 通过调用它注册所有C库中的函数,并将它们存储在适当的位置。
* 此函数的命名规则应遵循:
* 1、使用"luaopen_"作为前缀。
* 2、前缀之后的名字将作为"require"的参数。
*/
extern "C" int luaopen_mylib(lua_State *L )
{
/* void luaL_newlib (lua_State *L, const luaL_Reg l[]);
* 创建一个新的"table",并将"l"中所列出的函数注册为"table"的域。
*/
luaL_newlib(L, funclist);
return 1;
}
次に、gcc -shared -fPIC c_so.cpp -o mylib.so -I / home / lk / my_skynet_learning / skynet / 3rd / lua /をコンパイルします。
コンパイル後、mylib.soを取得します
testso.lua
local mylib = require "mylib"
local i = mylib.add(1, 2)
print(i)
local j = mylib.show('真的太多坑了')
結果は以下のとおりです。
オンライン検索は本当にあらゆる種類の落とし穴です。ねえ。