(原)lua使用ffi调用c程序的函数
转载请注明出处:
http://www.cnblogs.com/darkknightzh/p/5812763.html
参考网址:
http://luajit.org/ext_ffi_semantics.html#convert_fromlua
https://github.com/szagoruyko/loadcaffe
1. 新建calcmath.cpp,输入:
#include <iostream>
#include <cmath>
#include <stdio.h>
//using namespace std; extern "C" {
float isquare(float val);
double isqrt(double val);
void ivecadd(double* a, double* b, int len);
} float isquare(float val)
{
return val*val;
} double isqrt(double val)
{
return sqrt(val);
} void ivecadd(double* a, double* b, int len)
{
for (int i = ; i < len; ++i)
{
a[i] = a[i] + b[i];
}
}
说明:包含三个函数:isquare计算平方,isqrt计算开方,ivecadd计算两个数组对应元素之和。
2. 在终端中输入:
g++ -shared -fPIC -o libcalcmath.so calcmath.cpp
此时当前文件夹内会生成libcalcmath.so。
说明:不能使用gcc,会提示如下错误:
undefined symbol: _ZNSt8ios_base4InitD1Ev
截图如下:
3. 新建调用该库的lua文件:calcmath.lua(名字随便),并输入:
calcmath = {} local ffi = require("ffi") ffi.cdef[[
float isquare(float val);
double isqrt(double val);
void ivecadd(double* a, double* b, int len);
]] calcmath.C = ffi.load('calcmath') --[[local squareVal = calcmath.C.isquare(5) -- call functions in this file
print(squareVal)
local sqrtVal = calcmath.C.isqrt(5)
print(sqrtVal) local a = ffi.new('double[2]', {5.2, 6.7})
local b = ffi.new("double[2]", {3, 7}) local x = ffi.cast('double&',a)
local y = ffi.cast('double&',a+1) calcmath.C.ivecadd(a, b, ffi.sizeof(a)/8)
print(tonumber(x), tonumber(y))
print(ffi.sizeof(a))
]]
说明:a上面注释的代码实际可以直接使用,此时在当前文件内直接调用c函数。如果只在当前文件使用calcmath,可以加上local,如local calcmath = {}。如果要在其他文件内使用calcmath,则不能加上local,否则会提示:
b 该文件名字如果为ffi.lua的话,可能不能在其他文件内成功调用(应该是与系统文件ffi.lua冲突):
也可能能调用成功(在另一台电脑上试了一下,如果用include则失败,如果用dofile则成功。。。)。
160830更新:刚才又试了一下,即便该文件名字为‘ffi.lua’,无论是include还是dofile,都能成功:test.lua的前6行如下:
local ffi = require("ffi") --include 'ffi.lua' -- this line and the following 2 line are both ok require 'paths'
paths.dofile('ffi.lua')
如果不加第一句require就不行。估计程序能区分开哪个是系统的库文件,哪个是当前的文件。。。先将就着这样理解吧。
c libcalcmath.so文件可以放在当前文件夹下,也可以放在/usr/lib下;不论放在当前文件夹还是/usr/lib下,代码中均不用加上lib及.so,ffi.load 时会自动添加。当然在代码中也可以加上,如libcalcmath或libcalcmath.so或calcmath.so。我这边试了,如果放在其他文件夹下,需要使用绝对路径,并且需要使用库的完整名libcalcmath.so,如:/home/XXX/libcalcmath.so,否则会提示:
4. 新建测试程序test.lua,并输入:
local ffi = require("ffi") --include 'calcmath.lua' -- this line and the following 2 line are both ok require 'paths'
paths.dofile('calcmath.lua') local C = calcmath.C local squareVal = C.isquare()
print(squareVal)
local sqrtVal = C.isqrt()
print(sqrtVal) local a = ffi.new('double[2]', {5.2, 6.7})
local b = ffi.new("double[2]", {, }) local x = ffi.cast('double&',a)
local y = ffi.cast('double&',a+) C.ivecadd(a, b, ffi.sizeof(a)/)
print(tonumber(x), tonumber(y))
print(ffi.sizeof(a))
说明:a第一句local ffi = require("ffi")必须要,否则下面的ffi.new无法使用。
b 不确定是否需要释放new出来的内存。。。(以后碰到了再说吧)。
5. 结果:
使用th test.lua结果如下:
无法使用lua test.lua,会提示如下的错误:
使用luajit test.lua,结果如下:
说明:
如果isqrt中参数类型使用float的话,精度会有损失,结果为:
2.2360680103302
使用double后,结果为:
2.2360679774998
使用计算器的结果:
2.2360679774997896964091736687313
可见,使用double后,精度范围内结果一致。
(原)lua使用ffi调用c程序的函数的更多相关文章
- lua使用ffi调用c程序的函数
参考: https://blog.csdn.net/weiwangchao_/article/details/16880401 http://luajit.org/ext_c_api.html h ...
- C程序与Lua脚本相互调用
Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...
- Python基础笔记系列十四:python无缝调用c程序
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python语言可以对c程序代码进行调用,以弥补python语言低性能的缺 ...
- lua 15 协程-协同程序
转自:http://www.runoob.com/lua/lua-coroutine.html 什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈 ...
- MATLAB调用C程序、调试和LDPC译码
MATLAB是一个很好用的工具.利用MATLAB脚本进行科学计算也特别方便快捷.但是代码存在较多循环时,MATLAB运行速度极慢.如果不想放弃MATLAB中大量方便使用的库,又希望代码能迅速快捷的运行 ...
- 在ORACLE触发器里调用JAVA程序
因为项目需要,有一个已经写好的Java程序,想要在Oracle某个表的触发器中调用,以使得每次数据更新时,调用这个JAVA程序,来修改后台某个数据. 现将过程记录如下: 1.编写JAVA程序 publ ...
- Oracle触发器反向调用Java程序
导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了, 1.操作系统需要拥有支持loadjava命令的jdk. 2.加载j ...
- C/C++程序通过动态链接库调用MATLAB程序
C/C++程序通过动态链接库调用MATLAB程序 1 MATLAB编译器设置 需要设定对应的C++编译器才能编译.m文件生成可供C++调用的库文件. 在MATLAB命令行输入:mex –setup:然 ...
- tengine lua 开源一 调用内部接口高效发送文件
tengine lua 开源一 调用内部接口高效发送文件 开源自己封装的sendfile 模块,可以高效的通过lua发送文件 源码地址:https://github.com/weinyzhou/Lu ...
随机推荐
- inline-block样式间距
原始问题和解决方法请参考 淘宝UED官方博客:inline-block 前世今生 布局时采用行内块display:inline-block,发现元素之间有空隙,原因是由于空白字符引起的,详细见上面链接 ...
- javascript操作DOM的方法与属性
文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构. 将HTML代码分解为DOM节点层次图: ...
- [Apache系列]怎样在windows下配置apache vhost
找到你的Apache安装目录,下图为小编的Apache安装的目录 2 点击conf文件夹 进入配置目录,找到httpd.conf 文件, 3 打开httpd.conf 文件,如图, 找到地475行, ...
- centos在安装apache2.4版本的时候遇到ARP not found解决办法
今日编译apache时出错: #./configure --prefix……检查编辑环境时出现: checking for APR... noconfigure: error: APR not fou ...
- 接入SDK
管理提醒: 本帖被 fm2010 设置为精华(2014-11-12) http://www.cocoachina.com/bbs/read.php?tid-239087.html 本帖属于Co ...
- U盘启动时无USB-HDD选项的解决方案
今天在使用一块老板子的时候 发现没有USB-HDD启动项 在启动顺序中只有 USB-ZIP(ZIP) -FDD(软盘) -CDROM(光驱) 1.插入U盘 2.开机 3.在BIOS中找到Hard D ...
- oracle的resetlogs机制浅析
oracle的resetlogs机制浅析 alter database open resetlogs 这个命令我想大家都很熟悉了,那有没有想过这个resetlogs选项为什么要用?什么时候用?它的原理 ...
- Chrome小技巧:如何下载离线版安装文件
每当chrome有更新之后,都有不少用户想要下载离线版的安装文件,但苦于找不到下载地址而发愁,其实这个问题很简单,下面我来分享一下方法(仅针对Windows操作系统): 对于稳定版(正式版)Chrom ...
- Asp.net MVC中的ViewData与ViewBag(转)
在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下: ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从 ...
- 【转】手机web——自适应网页设计(html/css控制)
手机web——自适应网页设计(html/css控制) 就目前形势来看,Web App 正是眼下的一个趋势和潮流,但是,对于Web App的设计可能大家有的不是很了解,下面就将整理好的网页设计的技巧奉献 ...