nodejs与c/c++交互目前主流的方式有两种,node addon c++ 和 node-ffi .

1、node addon c++

1)nodejs从c语言读取数据

addon.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> typedef struct
{
double lon;
double lat;
}gps_info_t; gps_info_t* gps; void get_gps_shm_init(void)
{
gps = (gps_info_t *)malloc(sizeof(gps_info_t));
} Napi::Object CreateObject(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object obj = Napi::Object::New(env); gps->lon = 55.5;
gps->lat = 66.6; printf("send lon: %f\n", gps->lon);
printf("send lat: %f\n", gps->lat); obj.Set(Napi::String::New(env, "lon"), gps->lon);
obj.Set(Napi::String::New(env, "lat"), gps->lat); return obj;
} Napi::Object Init(Napi::Env env, Napi::Object exports) {
get_gps_shm_init();
return Napi::Function::New(env, CreateObject, "createObject");
} NODE_API_MODULE(addon, Init)

addon.js

var addon = require('bindings')('addon');

var obj = addon('gps');

console.log(obj.lon);
console.log(obj.lat); module.exports.obj = obj;

2)nodejs向c语言写数据

addon.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> typedef struct
{
char *user_name;
char *passwd;
char *dev_id;
}user_info_t; user_info_t* user; void put_user_info_shm_init(void)
{
user = (user_info_t *)malloc(sizeof(user_info_t));
user->user_name = (char*)malloc(*sizeof(char));
user->passwd = (char*)malloc(*sizeof(char));
user->dev_id = (char*)malloc(*sizeof(char));
} Napi::Object CreateObject(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object obj = Napi::Object::New(env); memset(user->user_name, , );
memset(user->passwd, , );
memset(user->dev_id, , );
memcpy(user->user_name, info[].ToString(), );
memcpy(user->passwd, info[].ToString(), );
memcpy(user->dev_id, info[].ToString(), ); printf("recv user info (user_name): %s\n", user->user_name);
printf("recv user info (passwd): %s\n", user->passwd);
printf("recv user info (dev_id): %s\n", user->dev_id); return obj;
} Napi::Object Init(Napi::Env env, Napi::Object exports) {
put_user_info_shm_init();
return Napi::Function::New(env, CreateObject, "createObject");
} NODE_API_MODULE(addon, Init)

addon.js

var addon = require('bindings')('addon');

var user_info = {
user_name = 'zdd';
passwd = '123';
dev_id = '65535'
} var obj = addon(user_info.user_name,user_info.passwd,user_info.dev_id); module.exports.user_info = user_info;

nodejs的C/C++拓展,将c/c++源码编译成js模板库

ubuntu下编译

node-gyp configure
node-gyp build

node addon.js

交叉编译
export CC=arm-linux-gnueabihf-gcc
export CXX=arm-linux-gnueabihf-g++
export LD=arm-linux-gnueabihf-ld
export RAINLIB=arm-linux-gnueabihf-rainlib
export AR=arm-linux-gnueabihf-ar
export LINK=arm-linux-gnueabihf-g++
node-gyp configure --arch=arm
node-gyp build

node addon.js

2、node-ffi

1)nodejs从c语言读取数据

factorial.c

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h> #if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif typedef struct
{
double lon;
double lat;
}gps_info_t; gps_info_t* gps; void get_gps_shm_init(void)
{
gps = (gps_info_t *)malloc(sizeof(gps_info_t));
} EXPORT gps_info_t* get_gps_info(void) {
get_gps_shm_init();
gps->lon = 55.5;
gps->lat = 55.5;return gps;
}

factorial.js

var ffi = require('../node-ffi-master/')
var refStruct = require('ref-struct');
var refArray = require('ref-array');
var ref = require('ref'); //gps date struct
var gps = refStruct({
'lon':ref.types.double,
'lat':ref.types.double,
}); var gpsStructArrayType = refArray(gps);
var gps_info = gpsStructArrayType(); var libfactorial = ffi.Library('./libfactorial', {
'get_gps_info': [ gpsStructArrayType, [ 'void' ] ],
}); gps_info = libfactorial.get_gps_info() console.log('Your output: ' + gps_info[].lon)
console.log('Your output: ' + gps_info[].lat)

2)nodejs向c语言写数据

factorial.c

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h> #if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif typedef struct
{
char *user_name;
char *passwd;
char *dev_id;
}user_info_t; user_info_t* user; void put_user_info_shm_init(void)
{
user = (user_info_t *)malloc(sizeof(user_info_t));
user->user_name = (char*)malloc(*sizeof(char));
user->passwd = (char*)malloc(*sizeof(char));
user->dev_id = (char*)malloc(*sizeof(char));
} EXPORT void put_user_info(user_info_t* user_info) {
put_user_info_shm_init();
printf("get userinfo(user_name):%s",user_info->user_name);
printf("get userinfo(user_name):%s",user_info->passwd);
printf("get userinfo(user_name):%s",user_info->dev_id);
}

factorial.js

var ffi = require('../node-ffi-master/')
var refStruct = require('ref-struct');
var refArray = require('ref-array');
var ref = require('ref'); //ui date struct
var user = refStruct({
'user_name':'string',
'passwd':'string',
'dev_id':'string',
}); var userStructArrayType = refArray(user);
var user_info = userStructArrayType(); user_info[].user_name = 'zdd';
user_info[].passwd = '';
user_info[].dev_id = ''; var libfactorial = ffi.Library('./libfactorial', {
'put_user_info': [ 'void', [ userStructArrayType ] ]
}); libfactorial.put_user_info(user_info) console.log('Your input: ' + user_info[].user_name)
console.log('Your input: ' + user_info[].passwd)
console.log('Your input: ' + user_info[].dev_id)

gcc / arm-linux-gnueabihf-gcc -shared -fpic factorial.c -o libfactorial.so

node factorial.js

上面两种方式写了个demo放在github上了

https://github.com/zhoudd1/nodejs_call_c_cc

3、还有一种小众化的方式

通过child_process 方式调用EXE进程来实现数据交互。

var cp= require('child_process');
//同步的方式

letout = cp.execFileSync("testdll.exe", ["arg1","arg2"],{});

//异步的方式

cp.execFile("testdll.exe", ["arg1","arg2"], {}, (error, stdout, stderr) => {
    console.log(stdout);
})
 

这种方式NODE 会接管stdout 和 stderr ,exe中把结果通过 printf 输出。
缺点:需要先生成EXE,EXE 中调用 DLL/so 并且返回结果。
优点:不需要配置 FFI,不受DLL/so 的影响

更多细节

https://www.cnblogs.com/chyingp/p/node-learning-guide-child_process.html

https://blog.csdn.net/zeping891103/article/details/52230175

nodejs与c语言交互应用实例的更多相关文章

  1. python与c语言交互应用实例

    1.python向c语言写数据 1) 先将接收端编译成一个共享链接库gcc/arm-linux-gnueabihf-gcc -o bluetooth_proxy.so -shared -fPIC bl ...

  2. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  3. linux下C语言多线程编程实例

    用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...

  4. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  5. FFI (语言交互接口(Foreign Function Interface))

    FFI(Foreign Function Interface)是用来与其它语言交互的接口, 在有些语言里面称为语言绑定(language bindings), Java 里面一般称为 JNI(Java ...

  6. nodejs实现前后端交互

    本人nodejs入门级选手,站在巨人(文殊)的肩膀上学习了一些相关知识,有幸在项目中使用nodejs实现了前后端交互,因此,将整个交互过程记录下来,方便以后学习. 本文从宏观讲述nodejs实现前后端 ...

  7. react UI交互 简单实例

    <body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...

  8. nodejs+mongoose操作mongodb副本集实例

    继上一篇设置mongodb副本集之后,开始使用nodejs访问mongodb副本集: 1:创建项目     express 项目名称 2:npm install mongoose    安装mongo ...

  9. 第4章-Vue.js 交互及实例的生命周期

    一.学习目标 了解实例生命周期的过程 理解钩子函数的作用 掌握Vue.js过滤器的使用方法 (重点) 能够使用网络请求进行前后端交互 (重点.难点) 二.交互的基本概念 2.1.前端和后端的概念 说明 ...

随机推荐

  1. Sys未定义处理方法

    网上很多方法都试过,但是我发现,如果我把iis的端口号换一下,然后重新部署,就正常了,然后你可以再换回原来的端口号,也不会再报错了,应该是微软的一个bug,不知道大伙有什么更好的办法么

  2. 利用CSS生成精美细线Table表格

    精美的表格是前端开发用到的一个组件,很多时候我们利用复杂的页面style代码,来生成这样的表格,造成了页面的修改性和可读性都非常差.这里推荐直接使用css来产生一个细线表格. 使用方法也很简单: 第一 ...

  3. /sys/kernel/debug/gpio

    在使用GPIO的时候,有时候不知道GPIO的状态,也不知道在内核中GPIO是否申请成功. 可以通过/sys/kernel/debug/gpio这个文件来查看.这个文件显示了申请成功的GPIO的输入输出 ...

  4. ResultSet是结果集对象

    ResultSet是结果集对象 DriverManager管理一组驱动程序 PreparedStatement预编译的,用来发送和执行SQL语句的

  5. 算法优化:rgb向yuv的转化最优算法

    朋友曾经给我推荐了一个有关代码优化的pdf文档<让你的软件飞起来>,看完之后,感受颇深.为了推广其,同时也为了自己加深印象,故将其总结为word文档.下面就是其的详细内容总结,希望能于己于 ...

  6. 【BZOJ】1028: [JSOI2007]麻将(贪心+暴力)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1028 表示不会贪心QAQ 按顺序枚举,如果能形成刻子那么就形成刻子,否则形成顺子.orz 证明?:因 ...

  7. ubuntu被delete的文件位置

    在-/.local/share/Trash/files下边 可以通过 cd / find -name <filename> 找到盖文件的位置

  8. React-Native 样式指南

    https://github.com/doyoe/react-native-stylesheet-guide

  9. LAMP环境搭建博客

    背景: 公司要用到lamp环境,让我装,我就开始着手找资料,一般分为源码装和yum装,源码装很容易出错,所以我选择了yum装,. 服务器:aliyun服务器  centos6.8系统 按照第一个安装完 ...

  10. php 快速读取文件夹下文件列表

    在读取某个文件夹下的内容的时候 以前是使用 opendir readdir结合while循环过滤 . ..当前文件夹和父文件夹来操作的. 代码如下: 然后偶然发现了有scandir函数 可以扫描文件夹 ...