当前位置:网站首页>Detailed explanation of mutual call between C language and Lua
Detailed explanation of mutual call between C language and Lua
2022-06-11 06:30:00 【Quiet Zhiyuan 2021】
C Language and Lua Detailed explanation of mutual calls between
1. Write a C call Lua Of Demo Compile operation
add.c Content
// You need include These are a few lua The header file
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
lua_State* L;
int
luaadd(int x, int y)
{
int sum;
/* Function name */
lua_getglobal(L,"add");
/* Parameter stack */
lua_pushnumber(L, x);
/* Parameter stack */
lua_pushnumber(L, y);
/* Start calling functions , Yes 2 Parameters ,1 Return values */
lua_call(L, 2, 1);
/* Take out the return value */
sum = (int)lua_tonumber(L, -1);
/* Clear the stack of returned values */
lua_pop(L,1);
return sum;
}
int
main(int argc, char *argv[])
{
int sum;
L = luaL_newstate(); /* establish lua State machine */
luaL_openlibs(L); /* open Lua All in the state machine Lua Standard library */
/* load lua Script */
luaL_dofile(L, "add.lua");
/* call C function , This will call lua function */
sum = luaadd(99, 10);
printf("The sum is %d \n",sum);
/* eliminate Lua*/
lua_close(L);
return 0;
}
add.lua And C In the same category , Write a simple function inside , Give Way C call
function add(x,y)
print("this is a lua script")
return x + y
end
Okay , Finally, it's time to use GCC The stage of compilation , direct gcc add.c Let's see if we can .
Sure enough, the report was wrong !
This is because you didn't put add.c The functions inside are linked to the functions we compiled earlier lua Curry caused . How to let him specify which library to link ? see GCC The documentation of -l Parameter can specify the library to link
-l Parameters and -L Parameters
-l Parameters are used to specify the library that the program will link to ,-l The parameter is followed by the library name , So what does a library name have to do with a real library file name ?
Take the math library , His library name is m, His library file name is libm.so, It's easy to see , Put the header of the library file name lib And tail .so It's the name of the library
2. C Language call Lua Compilation problem summary
2.1 Correct compile command
Link to the original text :https://blog.csdn.net/uisoul/article/details/60137134
gcc -o test test.c -llua -lm -ldl
Let's try again , Compiled this time : test
Successful implementation !
2.2 problem 1: The lack of -lm Parameters
/usr/local/lib/liblua.a(lobject.o): In function `numarith': lobject.c:(.text+0xc8d): undefined reference to `fmod' lobject.c:(.text+0xcb8): undefined reference to `pow' /usr/local/lib/liblua.a(lvm.o): In function `luaV_execute':
lvm.c:(.text+0x2068): undefined reference to `pow' lvm.c:(.text+0x211c): undefined reference to `fmod' /usr/local/lib/liblua.a(lmathlib.o): In function `math_log10': lmathlib.c:(.text+0x21e): undefined reference to `log10'
/usr/local/lib/liblua.a(lmathlib.o): In function `math_pow': lmathlib.c:(.text+0x338): undefined reference to `pow'
........
2.3 problem 2: The lack of -ldl Parameters
/usr/local/lib/liblua.a(loadlib.o): In function `lookforfunc': loadlib.c:(.text+0x748): undefined reference to `dlsym'loadlib.c:(.text+0x7b3): undefined reference to `dlopen'loadlib.c:(.text+0x851): undefined reference to `dlerror'loadlib.c:(.text+0x871): undefined reference to
`dlerror'/usr/local/lib/liblua.a(loadlib.o): In function `gctm':loadlib.c:
(.text+0xa44): undefined reference to `dlclose'
Problem analysis
1、 Why does it show up undefined reference to ‘xxxxx’ error ?
First of all, it's a link error , Not a compilation error , That is to say, if this is the only mistake , Explain that there is no problem with your source code itself , You used the wrong parameters when compiling with the compiler , You didn't specify the library to be used by the linker , For example, some mathematical functions are used in your program , Then you have to specify in the compilation parameters that the program should link to the math library , The method is to add... In the compilation command line -lm.
2、-l Parameters and -L Parameters
-l Parameters It is used to specify the library to which the program will link ,-l The parameter is followed by the library name , So what does a library name have to do with a real library file name ? Take the math library , His library name is m, His library file name is libm.so, It's easy to see , Put the header of the library file name lib And tail .so It's the name of the library . Well, now we know how to get the library name , For example, we need to use a library provided by a third party called libtest.so, So we just need to libtest.so copy to /usr/lib in , Compile with -ltest Parameters , We can use libtest.so The library ( Of course want to use libtest.so Functions in the library , We also need to work with libtest.so Matching header file ). Put it in /lib and /usr/lib and /usr/local/lib The library in the library is used directly -l Parameters will link , But if the library files are not in these three directories , It's in other catalogues , At this time, we only use -l Parameter words , Links still go wrong , The error message is probably :“/usr/bin/ld: cannot find -lxxx”, That's the linker ld There 3 I can't find it in one catalog libxxx.so, Here's another parameter -L That comes in handy , For example, common X11 The library of , It on /usr/X11R6/lib Under the table of contents , We're going to compile with -L/usr/X11R6/lib -lX11 Parameters ,-L The parameter is followed by the name of the directory where the library file is located . Let's take... For example libtest.so Put it in /aaa/bbb/ccc Under the table of contents , The link parameter is -L/aaa/bbb/ccc -ltest in addition , Most of the libxxxx.so It's just a link , With RH9 For example , such as libm.so It links to /lib/libm.so.x,/lib/libm.so.6 And link to /lib/libm-2.3.2.so, If there is no such link , There will still be mistakes , because ld I'll just find libxxxx.so, So if you're going to use xxxx library , And only libxxxx.so.x perhaps libxxxx-x.x.x.so, Just make a link ln -s libxxxx-x.x.x.so libxxxx.so
Reference material :
http://blog.csdn.net/uisoul/article/details/60135764
http://blog.csdn.net/uisoul/article/details/60135383
http://blog.csdn.net/uisoul/article/details/60135764
3 How to make Lua call C?( among 3 Ways of planting )
Lua call C, What I've learned is 3 Ways of planting
The way 1. By means of C Register functions in lua call
The way 2. Encapsulated into c Dynamic link library , stay lua in require
The way 3. stay LuaJIT It can be used inside ffi High performance call C( however IOS I don't support LuaJIT..)
3.1 The way 1: stay C Register functions in Lua
lua Provides lua_register Function registration C Function gives lua End calls
hello.c
#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int l_SayHello(lua_State *L)
{
const char *d = luaL_checkstring(L, 1);// To obtain parameters , String type
int len = strlen(d);
char str[100] = "hello ";
strcat(str, d);
lua_pushstring(L, str); /* Return to lua Value stack of */
return 1;
}
int
main(int argc, char *argv[])
{
lua_State *L = luaL_newstate(); /* establish lua State machine */
luaL_openlibs(L); /* open Lua All in the state machine Lua Standard library */
lua_register(L, "SayHello", l_SayHello);// register C Function to lua
const char* testfunc = "print(SayHello('lijia'))";//lua Call in c function
if(luaL_dostring(L, testfunc)) // perform Lua command .
printf("Failed to invoke.\n");
/* eliminate Lua*/
lua_close(L);
return 0;
}
gcc -o hello hello.c -llua Compile implementation
3.2 The way 2: call C Dynamic link library
Create a mylib.c The file of , Then we compile it into a dynamic link library .
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
/* All registered to Lua Of C Function has * "typedef int (*lua_CFunction) (lua_State *L);" The prototype of the . */
static int l_sin(lua_State *L)
{
// If the element at the index in a given virtual stack can be converted to a number , Returns the converted number , Otherwise, the report will be wrong .
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d)); /* push result */
/* You can see here ,C You can return to Lua Multiple results , * Through multiple calls lua_push*(), after return Number of returned results . */
return 1; /* number of results */
}
/* Need one "luaL_Reg" Type of structure , Each of these elements corresponds to one provided to Lua Function of . * Each element contains this function in Lua The name of , And the function in C Function pointers in the library . * The last element is “ Sentinel element ”( Two "NULL"), Used to tell Lua No other functions need to be registered . */
static const struct luaL_Reg mylib[] = {
{
"mysin", l_sin},
{
NULL, NULL}
};
/* This function is C In the library “ Special functions ”. * Register all... By calling it C Functions in the library , And store them in the right place . * The naming rules for this function should follow : * 1、 Use "luaopen_" As a prefix . * 2、 The name after the prefix will be used as "require" Parameters of . */
extern int luaopen_mylib(lua_State* L)
{
/* void luaL_newlib (lua_State *L, const luaL_Reg l[]); * Create a new "table", And will "l" The functions listed in are registered as "table" The domain of . */
luaL_newlib(L, mylib);
return 1;
}
Use gcc -o mylib.so -fPIC -shared mylib.c -llua -ldl Translate it into so
And then create a lua file , Compiled us c Library brought in .
--[[ here "require" The parameter corresponding to C In the library "luaopen_mylib()" Medium "mylib". C The library is right there "a.lua" The same level directory ,"require" Can find .]]
local mylib = require "mylib"
-- The result is the same as in the above example , But here is by calling C The function implementation in the library .
print(mylib.mysin(3.14 / 2)) --> 0.99999968293183
perform a.lua file , Report a mistake later , say Lua There are multiple virtual machines !
lua: multiple Lua VMs detected
Why? ? I checked some data and found that because lua The default compilation is static link library , This will lead to multiple links VM Conflict .
So let's compile another lua The interpreter dynamically links .
mylua.c
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_loadfile(L, "a.lua") || lua_pcall(L, 0, 0, 0)) {
printf("%s", lua_tostring(L, -1));
}
}
gcc -o mylua mylua.c -llua -ldl -lm -Wall
So you can compile mylua Executable file
In command line ./mylua perform , Successfully printed out 0.99999968293183
3.3 summary
gcc command , compile lua, compile C Dynamic link libraries have been less exposed before . So I climbed a lot of pits , Ha ha ha . Next, we need to study how to c Parsing binary protocols in lua call , stay c How to package in luatable
Reference material :
https://www.cnblogs.com/pied/archive/2012/10/26/2741601.html
http://blog.csdn.net/vermilliontear/article/details/50947379
http://blog.csdn.net/casularm/article/details/316149
Okay , The above is the whole content of this article , I hope the content of this article has a certain reference value for your study or work , If you have any questions, you can leave a message , Thank you for your support for script house .
边栏推荐
- 个人常用软件及浏览器插件分享
- Shandong University machine learning experiment 5 SVM
- UEFI finding PCI devices
- []==! []
- verilog实现双目摄像头图像数据采集并modelsim仿真,最终matlab进行图像显示
- FPGA面试题目笔记(四)—— 序列检测器、跨时钟域中的格雷码、乒乓操作、降低静动态损耗、定点化无损误差、恢复时间和移除时间
- call和apply和bind的区别
- Docker installation of MySQL and redis
- Handwritten a message queue in two ways
- FPGA面试题目笔记(三)——跨时钟域中握手信号同步的实现、任意分频、进制转换、RAM存储器等、原码反码和补码
猜你喜欢
![[reading this article is enough!!! Easy to understand] confidence level understanding (95% confidence level and confidence interval)](/img/d6/e61ba5bad2b2847378c4547ce0780d.jpg)
[reading this article is enough!!! Easy to understand] confidence level understanding (95% confidence level and confidence interval)

Shandong University machine learning experiment 7 pca+ SVM face recognition

Graphsage paper reading

Using Metasploit Trojan horse for remote control

Training and testing of super score model in mmediting

学好C语言从关键字开始

Mongodb installation

通过两种方式手写一个消息队列

Autojs, read one line, delete one line, and stop scripts other than your own

Convert text label of dataset to digital label
随机推荐
Shandong University machine learning experiment 7 pca+ SVM face recognition
Matlab实现均值滤波与FPGA进行对比,并采用modelsim波形仿真
The difference between call and apply and bind
This point of arrow function
Throttling and anti shake
C language war "minesweeping"
Who is stronger, zip or 7-Zip, and how to choose?
Wechat applet (authorized login) (not recommended, click the home page to view the updated authorized login)
Chapter 1 of machine learning [series] linear regression model
021-MongoDB数据库从入门到放弃
Ethical discussion on reptile Technology
Notes sur les questions d'entrevue de la FPGA (IV) - - détecteur de séquence, Code gris dans le domaine de l'horloge croisée, opération de ping - pong, réduction de la perte statique et dynamique, err
CCS安装编译器的方法
How to arrange the dataframe from small to large according to the absolute value of a column?
个人常用软件及浏览器插件分享
arguments......
CCF 2013 12-4 interesting numbers
Teach you to write word formula
EasyGBS接入的设备视频直播突然全部无法播放是为什么?数据库读写不够
Handwriting promise [02] - asynchronous logic implementation