经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Lua » 查看文章
LuaLaTeX调用外部Lua程序与C语言编写的动态链接库
来源:cnblogs  作者:陆巍  时间:2019/1/11 9:54:53  对本文有异议


??在LuaLaTeX编译方式下,虽然可以直接在tex文件中编写Lua代码,但会受到LaTeX的影响,编写中并不是很便利。所以我在实际使用中一般都把Lua代码的主体部分放在LaTeX的外部,这样可以完全按照以往的编程习惯去编写。我以前所在的公司,曾经在机器人运动控制系统中使用过Lua,但因为我没有负责那一部分,所以只是知道有Lua这么个脚本语言,并没有实际编写过。这几天才开始学习编写Lua代码,所以还有很多不足,请多多体谅。下面介绍一下我的用法。

1、开发环境

  • 操作系统:Ubuntu 16.04 64位桌面版

  • LaTeX工具:TeXstudio 2.10.8

  • 编译方式:LuaLaTeX

  • Lua编辑工具:Visual Studio Code 1.30.2

  • Lua插件:vscode-lua 0.12.4

2、LaTeX中使用Lua

??我使用的宏包是luacode。在安装TeXstudio后,我顺手就安装了texlive-all,这个宏包包含在里面。在TeXstudio中,右键点击\uspackage{luacode}弹出的菜单中,可以打开luacode的说明文档。
??luacode中提供了四种使用Lua代码的命令,他们的差别如下表(不好意思,本来想用markdown绘制表格,但表格的标题栏始终显示不出来,只好放截图了。):

从表中可以看到不同命令的差异。我通常使用的是\luaexec命令。调用方式就是在\luaexec{}的大括号内编写Lua代码。通过以上命令来编写Lua代码,一方面因为受到LaTeX格式的影响,会有很多不便;另一方面也不符合我们的软件设计原则。所以需要把Lua的归给Lua,不要全都放在这里,这里仅保留调用代码。

3、调用外部Lua代码

??调用方式很简单,一般有两种。一种是用require,另一种是用dofile。但要注意的是package.path在LaTeX中好像并没有用,我的代码在Lua命令行模式下调用没有问题,在LaTeX中就不行,具体原因还不清楚。现在我是在require中直接加上路径。例如:

  1. % ------ 类图 ------
  2. \newcommand{\umlClass}[2][]{%
  3. \luaexec{%
  4. require "lua/uml_class"
  5. local umlClass = UmlClass:new(nil, "#1", "#2")
  6. tex.sprint(umlClass:Draw())
  7. }%
  8. }%

??其中,uml_class.lua(调用时不用加扩展名)文件放在tex所在文件夹的子目录lua中。传入的参数#1与#2一定要放在双引号里面。输出方式就是tex.sprint(...)。

4、调用C编写的动态链接库

??这方面与单纯Lua下调用差不多,网上有很多例子,我就不多说了,直接贴上代码。

c 源代码:test.c

  1. // 博客园 陆巍的博客:https://www.cnblogs.com/atthefirst/
  2. #include <stdio.h>
  3. #include "/usr/local/include/luajit-2.0/lua.h"
  4. #include "/usr/local/include/luajit-2.0/lauxlib.h"
  5. #include "/usr/local/include/luajit-2.0/lualib.h"
  6. // 加上声明,以免编译时出现警告
  7. void luaL_setfuncs (lua_State* L, const luaL_Reg* l, int nup);
  8. static int Area(lua_State *L) {
  9. double radius = luaL_checknumber(L, 1);
  10. lua_pushnumber(L, 3.1416 * radius * radius);
  11. return 1;
  12. }
  13. static int Hello(lua_State *L) {
  14. char* str1= {"Hello, it's me."};
  15. lua_pushstring(L, str1);
  16. return 1;
  17. }
  18. static luaL_Reg RegLibs[] = {
  19. {"Area", Area},
  20. {"Hello", Hello},
  21. {NULL, NULL}
  22. };
  23. // 这里的函数名luaopen_test是有固定格式的,格式为:luaopen_你的库名
  24. int luaopen_test(lua_State* L) {
  25. lua_newtable(L);
  26. luaL_setfuncs(L, RegLibs, 0);
  27. return 1;
  28. }

??我的Lua是使用sudo apt install命令安装的,版本是5.2.4。在不同版本下,以上代码还有些不同,可参考网上文章介绍,比较多,不说了。这里只是把我实际验证过的代码发上来。

把test.c文件编译为动态链接库

  1. gcc -fPIC -shared -o test.so test.c

??我的gcc版本是5.4.0。

LaTeX中的调用代码

  1. // 博客园 陆巍的博客:https://www.cnblogs.com/atthefirst/
  2. \documentclass{article}%
  3. %
  4. \usepackage{ctex}%
  5. \usepackage{luacode}%
  6. %
  7. \setlength{\parindent}{0pt}%
  8. %
  9. \begin{document}%
  10. %
  11. LuaLaTeX使用Lua代码,Lua调用C动态链接库示例:\\\\%
  12. %
  13. \luaexec{%
  14. local test = require("test")
  15. str = "字符串示例:" .. test.Hello() .. "\\\\"
  16. tex.sprint(str)
  17. str = "数值计算示例,面积: " .. test.Area(6)
  18. tex.sprint(str)
  19. }%
  20. %
  21. \end{document}%

效果如下:

??通过以上方式,我们就把LaTeX、Lua与C联系在了一起,这样一来,对于程序员来说可以发挥的空间就很大了。

??这段时间我就在用Lua来编写在LaTeX中绘制UML图形的代码,原来是在XeLaTeX编译方式下,用的办法主要是pgf那一套(不过,通用性比Lua的强),但始终不怎么方便,所以这几天改用Lua来写,正在编写中。下面放一张图片:

??项目已经放在码云中,等编得差不多了再发给大家看。Lua的文字处理功能不错,暂时我在LaTeX的使用中还用不到C语言来编写代码。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号