通过ffi在nodejs中调用动态链接库(.so文件)

本文介绍了如何使用node-ffi在Node.js环境中调用C/C++编写的动态链接库(.so文件)。通过ffi,开发者可以避免重新编写后台服务的接口,直接利用已有的C接口进行密集计算任务。文章提供了调用动态链接库的步骤,包括ffi的安装、注意事项,以及调用C接口发送短信的实例。同时,还讨论了处理C指针类型的方法,展示了如何获取C接口指针内容的示例。
摘要由CSDN通过智能技术生成

概述

为什么要在node.js中调用动态链接库

  1. 由于腾讯体系下的许多公共的后台服务(L5, CKV, msgQ等)已经有了非常成熟的C/C++编写的API,以供应用程序调用,node.js作为在公司内新兴的后台runtime在调用这些公共服务的时候没必要再造一遍轮子,而是可以将这些API编译成.so文件直接使用。
  2. 对于一些密集计算型的任务可以由C++编写好模块,生成.so文件后由node.js调用。

ffi简介与安装

我们使用node-ffi来帮助我们调用动态链接库。

FFI的全称是Foreign Function Interface,该项目生来就是解决NodeJS的本地调用问题的,其流程就相当于Windows下的LoadLibrary()和GetProcAddress(),亦可以理解为NodeJS下的平台调用。为了调用一个小小的本地函数而创建一个addon实在是有点过头了,这个时候,FFI这把杀鸡刀就顺手得多了。有了它,本地调用变得异常简单,因为它在NodeJS环境中为JavaScript提供了一套强大的工具集用来调用动态链接库。

notice: 本人的node使用环境是64bit的Linux系统。
安装ffi:

  1. 全局或局部安装node-gyp: npm install -g node-gyp,装之前要安装python 2.7,而node-gyp不支持Python 3.x,所以安装了多个版本Python的读者得留意一下自己当前的Python版本了。Linux下pythonbrew一键搞定,Windows下还得去改环境变量。并且,如果你使用的node.js版本是4.0+,node-gyp的安装依赖支持C++11语法的gcc,你需要确定当前环境的gcc版本至少高于4.8。
  2. 安装ffi:npm install ffi

注意事项!

  • ffi只能调用C风格的模块。
  • 需要将C源码build成动态链接库以供调用,在Linux下将C源码build成.so文件,在windows下build成.dll文件。本文只阐述.so文件的调用方法,调用.dll差别不大。
  • 在Linux下如果使用C++编写的addon来调用.so文件,需要将.so文件为系统共享。具体方法可以参看ldconfig命令,这是一个Linux下的动态链接库管理命令。ldconfig命令的主要用途是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

煎蛋栗子

这里就不演示利用node-gyp将.cc文件生成.node文件了,一般我都是找后台同学帮我把C源码文件编译成.so文件,然后直接拿过来用!哈哈哈!
这个栗子是nodejs调用C接口发送短信,这个C的API也非常简单:

int send_msg(char * phone, char * content)

参数是手机号和短信内容,类型都是char *,返回的retcode是一个整型,返回0就代表发送成功,其他就是失败,方法名是send_msg。下面是如果利用ffi在nodejs中调用这个接口,该接口的源码已经被封装成libsend_msg.so这个动态链接库了,我们直接调用就好。

'use strict'
/**
 * 短信下发服务模块
 * 由于项目是使用node 5.0+,所以安装node-ffi模块需要依赖gcc 4.8+以上版本
 */

var ffi = require('ffi');

// int send_msg(char * phone, char * content)
var libm = ffi.Library(__dirname + '/msgQ/libsend_msg', {
   
	'send_msg': ['int', ['string', 'string']]
});

let smsExport = {
   
	sendMsg(opt) {
   
		let phone = opt.phone;
		let content = opt.text;

		// 调用c接口,发送短信
		let retcode = libm.send_m
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值