通过编译luaSQL调用ODBC连接Access以及给OpenResty(LuaJIT)编写简单的C扩展示例
来源:互联网 发布:sm3算法 国际标准 编辑:程序博客网 时间:2024/04/25 13:39
给OpenResty(LuaJIT)编写简单的C扩展示例以及通过编译luaSQL调用ODBC连接Access
前一篇文章写了一个通过ffi调用odbc连接mdb的一个库,当然,这个过程是很痛苦的……
于是我开始自我怀疑,luaJIT到底能不能使用lua的一些库?luaJIT按理说跟lua5.1版本是很接近的,那么接口的扩展方式也是一样的……
但是当我把luaSQL的odbc.dll拷进去,并且根据示例执行require(“luasql.odbc”)时,却提示“找不到指定的模块”……
这使我一度怀疑,luaJIT不能使用Lua的一些库……当然,现在要拨乱反正,证明这个想法是错误的……
在此之前,我们先编写一个简单的Hello world的C扩展给LuaJIT调用试试,这也是我的探索之路,相信在这个过程中,大家也会渐渐的明白到底问题在哪儿……
给OpenResty(LuaJIT)编写简单的C扩展示例
我们的扩展只有一个文件,那就是hello.c文件
//gcc lua51.dll hello.c -shared -Llua -Iinclude\luajit-2.1 -o hello.dll#include "lua.h"#include "lauxlib.h"#include "lualib.h"static const char* dohello(const char* src){printf(src);return "I'm OK!";}static int l_hello(lua_State* lua){const char *src = NULL;src= luaL_checkstring(lua, 1);//出栈获取源字符串const char * des = dohello(src); //somethinglua_pushstring(lua, des); //压栈返回给luareturn 1; //告诉lua返回了一个变量}//映射表,"doHello"为lua中的函数名,l_hello为真正C中的函数地址static const struct luaL_Reg libhello[] = {{"doHello", l_hello},{NULL, NULL},};//模块注册函数int luaopen_hello(lua_State* lua){//注册本模块中所有的功能函数,hello为模块名,libhello数组存储所有函数的映射关系luaL_register(lua, "hello", libhello);return 1;}我是通过MinGW进行编译的,把hello.c文件放到OpenResty目录中去,调用gcc命令进行编译:
gcc lua51.dll hello.c -shared -Llua -Iinclude\luajit-2.1 -o hello.dll编译成功后得到hello.dll,用luaJIT简单的测试一下:
> hello = require("hello")> r = hello.doHello("run~\n")run~> print(r)I'm OK!看来很成功~可惜我一开始做的时候不是这么顺利的……
在不断的调试过程中我发现了一点:
luaopen_后面跟着的字符串与luaL_register函数调用的第二个参数一定要一样!同时与dll的文件名也一定要一样!切记!切记!
这点很重要,是我经过多次的失败才发现的……这种要求大约也是我当年在java下编译HelloWorld一下午不成功的原因……当时都要哭了……
由于受这一点的启发,我似乎明白了我一直以来总是调用luasql_odbc不成功的原因……名称不一致……
下面介绍编译并调用luaSQL的正确姿势……
通过编译luaSQL调用ODBC连接Access
首先,去下载luaSQL的源码……
然后将下载下来的文件放到OpenResty的目录下的luasql目录中去,这么放的目的仅仅是为了引用include文件以及dll方便……
直接make odbc是不行的,我看了一下它的makefile,里面很多乱七八糟的变量需要修改,而且编译后的文件名默认是odbc.so……
仔细看看它引出的函数就知道,这个文件名是不能被LuaJIT正确加载的,需要改成luasql_odbc……
我为了描述省事,直接写了两条gcc命令来编译,这两条命令只会编译luaSQL_ODBC:
gcc -I../include/luajit-2.1 -DLUASQL_VERSION_NUMBER='"2.3.4"' -c src/luasql.c -o luasql.ogcc -I../include/luajit-2.1 -DLUASQL_VERSION_NUMBER='"2.3.4"' ../lua51.dll src/ls_odbc.c -o luasql_odbc.dll -shared luasql.o -lodbc32
这两条命令将生成两个文件,luasql.o和luasql_odbc.dll……
把luasql_odbc.dll放到OpenResty的目录中,写个lua脚本来调用一下试试吧……
还是用上次的那个test.mdb做示例吧……测试脚本testLuaSqlOdbc.lua的内容为:
local ENV = require("luasql_odbc")local env = ENV.odbc();local conn,err = env:connect("excuteSQL");if not conn thenprint(err);env:close();return -3;endfunction excuteSQL(sql)local n = conn:execute(sql);if not n thenprint("执行SQL失败");return -4;elseprint("影响行数:"..tostring(n));endreturn 0;endfunction itorator(cur)local row = {};return function()return cur:fetch(row,'a');endendfunction excuteQuery(sql)local cur = conn:execute(sql);if not cur thenprint("执行SQL失败");return -5;elselocal row = nil;for row in itorator(cur) dolocal out = {};for k,v in pairs(row) dotable.insert(out,k.."="..v)endprint(table.concat(out,","));endcur:close();endreturn 0;endexcuteSQL("insert into [test]([name],[value]) values('testluasqlodbc',123)");excuteQuery("select * from [test]");conn:close();env:close();return 0;
更多的luaSQL_odbc的调用接口在源码的doc里面看吧,这里只是简单的测试一下我们刚刚编译的东西能不能用……输出结果:
影响行数:1value=101,name=testOOO,id=1value=23,name=tesooo0,id=2value=100,name=testodbcConn1,id=3value=2333,name=tesodbcConntp1,id=4value=123,name=testluasqlodbc,id=5
应该是没什么大问题的……然而,luaSQL_odbc所实现的接口其实也不多,也是刚刚够用而已……
然而……让我踏入的大坑则是LuaSQL生成的动态链接库的文件名称不一致……
这致使我一直以为LuaSQL连接ODBC在OpenResty环境下是一个不能用的库……
于是也直接引发了我为LuaJIT写了一个ffi绑定库……
故事很曲折却是因为绕了一个大圈……分享出来,以免网友们重蹈覆辙……
- 通过编译luaSQL调用ODBC连接Access以及给OpenResty(LuaJIT)编写简单的C扩展示例
- Lua5.3简单的C扩展示例以及与OpenResty(LuaJIT)的兼容编译
- nginx静态编译luajit (openresty)
- Java连接ODBC数据源的简单示例
- c编写php扩展简单示例
- 用Access通过ODBC连接MySQL数据库的方法
- LuaJIT(OpenResty)调用iconv动态链接库转码
- openresty 应用打包并使用luajit编译lua代码实现简单加密
- java连接ACCESS数据库的简单示例
- lua连接数据库之luasql ------ luasql连接mysql数据库 及 luasql源码编译
- lua连接数据库之luasql ------ luasql连接mysql数据库 及 luasql源码编译
- luasql扩展
- C语言ODBC连接ACCESS数据库
- DLL的编写与调用,简单示例
- QT ODBC方式连接MS SQLSERVER2000/2005、ACCESS示例
- MFC 代码配置ACCESS的ODBC连接
- 通过odbc,c#连接pg数据库
- C API 通过ODBC 连接数据库MYSQL
- shm_comm
- "can't supply flags when constructing one RegExp from another"
- (十五)Reactnative不同Navigator 之间的传值
- 1.uboot的前世今生
- 贝尔数 hdu4767 (矩阵快速幂+中国剩余定理+bell数+Stirling数+欧几里德)
- 通过编译luaSQL调用ODBC连接Access以及给OpenResty(LuaJIT)编写简单的C扩展示例
- 条件编译
- ECSHOP漏洞集:http://sebug.net/appdir/ECSHOP
- 指针的引用和返回指针的引用
- 数据类型的笔记整理
- DTS和PTS
- [NOI2005] 维护数列
- 笔记
- DataSet和DataTable有用的方法