ffi动态链接库的使用

Posted first-semon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ffi动态链接库的使用相关的知识,希望对你有一定的参考价值。

最进项目中使用到了socketproc通信,但是这样有一点不是很好,必须单独启动一个进程来执行代码中的shell命令,后面想在nginx+lua的环境下使用openresty中的lua-resty-shell,但是在后续阅读源码说明的时候发现依赖关系过于复杂,会导致引入的openresty模块越来越堵。但是发现归根结底是对ffi库的调用,什么是ffi库?

说白一点:ffi动态库就是lua语言调用底层C语言的一系列接口,而ffi动态库日空了非常方便的编码风格,来时用字完成自己的功能。来看一下如何使用ffi库。

首先下载源码到自己的环境中进行编译。需要注意的是这个插件根据环境的不同生成的动态库不能相互使用的,楼主在过程中就烦了这个错误,将ubuntu环境下的动态库移动到centOS下使用失败。

首先make 会发现有两个找不到的,这时候就需要你手动更改Makefile中的PKG_CONFIG_PATH和lua的路径,改正之后make 成功,就会看到生成了ffi.so

然后将动态库拷贝到nginx的conf同一级目录下的lualib路径下,再将此路径添加到lua的cpath中,就可以使用了,就像下面一样:

package.cpath= "/usr/local/nginx-1.16.0/lualib/?.so;;"..package.cpath
local ffi = require("ffi")
local ffiShell = ffi.load("shellTest")

ffi.cdef[[
struct dummy{};
double sqrt(double x);
int gethostname(char *name,size_t len);
char* Run(const char* cmd);
]]

local dat =  ffiShell.Run(ls -al /tmp)
ngx.print(ffi.string(dat))

local int_t = ffi.typeof("int")
local char_arr_t = ffi.typeof("char[?]")

local a_int = ffi.new(int_t)
local char_arr=char_arr_t(10)

local x = ffi.C.sqrt(5)
ngx.print(x)

ffi.fill(char_arr,10)
ffi.C.gethostname(char_arr,10)
--ngx.print(char_arr)
ngx.print(ffi.string(char_arr))
--ngx.print(char_arr[0])

ngx.say(" call ffi.so!")

--ngx.say(ffiShell.Run("ls -al "))
--ffi.C.system("ls -al /usr/local")
shellTest是楼主自己使用C语言中的popen函数写的一个调用shell命令接口的动态链接库
#include "shellTest.h"
char* Run(const char* shellCmd){
/*      int ret = system(shellCmd);
        if(ret  < 0){
                char errInfo[128];
                sprintf(errInfo,"system call shellCmd error,ret:%d",ret);
                return errInfo;
        }else if(ret == 0){
                return "system fork failed";
        }else{
                return "shellCmd call successful!";
        }
*/

        char buf[1024];
        FILE *fp=popen(shellCmd,"r");
        fgets(buf,sizeof(buf),fp);
        //fscanf(fp,"%s",buf);
        //printf("%s",buf);
        pclose(fp);
        return buf;

}

头文件

#ifndef __SHELLCMD_H
#define __SHELLCMD_H
#include <stdio.h>
#include <stdlib.h>

char* Run(const char* shellCmd);


#endif

可能贴出来的代码有问题,需要大家在使用的时候进行简单的修改

以上是关于ffi动态链接库的使用的主要内容,如果未能解决你的问题,请参考以下文章

Node.js使用ffi-napi,ref-napi,ref-array-napi,ref-struct-napi调用动态库

动态链接库和静态链接库的区别简述

常用动态链接库的DLL都有哪些?

Linux动态链接库的使用

如何使用node.js中的C ++库?

如何使用cmake生成基于静态库的动态链接库