目录:专题:让C++给node做技能加持(一)环境搭建,项目运行
NodeJs调用C++方法
前面的章节,我们已经搭建好了全体打包的运行环境,接下来,让我们抛开官网的demo,自己写一些大略的C++代码供NodeJs调用。
先来创建一个空目录

mkdir demo && cd demo
创建两个文件。Calc.h, Calc.cc
解释:这里的.h文件是C++的头文件,.cc是c++的紧张逻辑代码文件
我们须要定义两个方法,一个做两个数的相加,返回结果,还有一个是传入一个字符串,返回一个新的字符串。
//定义calc.h头文件#pragma once//#pragma once是一个比较常用的C/C++预处理指令,只要在头文件的最开始加入这条预处理指令,就能够担保头文件只被编译一次。#include <string>class Calc{ public: static double add(int a, int b); static std::string reverse(std::string arr);};//这里利用到了C++类的观点,有些ES6根本的基本都能看明白,定义了一个Calc的类,并定义了两个可供外界访问的//静态方法
再来看下Calc.cc文件
#include "Calc.h"//引入刚定义好的头文件#include <string>using namespace std;//要想用string 须要引入std全名空间double Calc::add(int a,int b){ return a + b;}string Calc::reverse(string str) { return str + "-> 畅哥聊技能 ^_^";}//这里实现了刚才头文件里面方法。调用静态方法我们在ES6中是直接通过类名.静态方法,C++中些许的差异,//通过类名::静态方法名,像php
方法的实现也很大略。
接下来我们开始编译了。
解释:这样的C++代码是不能直接被我们的V8调用,我们须要对C++进行加工处理下。
重点来了!
!
!
//1、先将.cc文件编译成 .o 文件 我们采取g++命令g++ -c Calc.cc
天生了Calc.o文件
天生了.o文件后,我们还不能直接用它,我们须要做二次编译
ar -crv libCalc.a Calc.o//libCalc.a将是我们终极要的文件
终极的.a文件天生了
接着,我们要开始创建我们node-gyp的配置文件了,binding.gyp
{ "targets": [ { "target_name": "test", "sources": [ "test.cc" ], "libraries":["../libCalc.a"] } ]}//参数libraries 指向了我们刚打包出来的.a文件。
接下来我们开始创建我们的v8测试文件了,test.cc
#include <node.h>#include "./Calc.h"//引入刚才我们创建好的.h头文件#include <string>using namespace std;namespace MyDemo { //引入v8干系类型,用于与C++交互 using v8::Exception; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; using v8::Value; void Add(const FunctionCallbackInfo<Value>& args) { Isolate isolate = args.GetIsolate(); //引入了头文件后,我们就可以调用里面的方法了。 //args是用来吸收我们从node传过来的参数。下面是取number类型的数据。 double value = Calc::add(args[0].As<Number>()->Value(),args[1].As<Number>()->Value());//isolate是一个node与C++链接的管道 指针工具 Local<Number> num = Number::New(isolate, value);//末了将打算后的结果num返回给node端。 args.GetReturnValue().Set(num); } void Reverse(const FunctionCallbackInfo<Value>& args) { Isolate isolate = args.GetIsolate(); //通过吸收args吸收node传过来的参数,并转成v8类型的字符串。 String::Utf8Value param1(args[0]->ToString()); //得到的param1工具是一个指针工具,它指向的是一个内存地址, //以是我们在调用Calc::reverse的方法的时候须要将param1指针解引用拿到对应的字符串值 // param1 便是解引用,拿到详细的字符串。 string str = Calc::reverse(param1); Local<String> val = String::NewFromUtf8(isolate,str.c_str()); // Calc::reverse(param1);返回的是一个C++ 的 string类型的数据。我们还不能直接返回 //详细的问题,我们上一个章节已经做过解释了。须要经由 str.c_str()处理下。 args.GetReturnValue().Set(val); //末了将结果返回给node端 } void Init(Local<Object> exports) { //向nodejs导出两个方法、 NODE_SET_METHOD(exports,"add", Add); NODE_SET_METHOD(exports,"reverse",Reverse); } NODE_MODULE(addon, Init)}
接下来我们看下编译过程:
成功编译
末了来调用下吧。创建index.js
成功调用了C++的方法
到这里,我们已经成功调用了C++编写的方法了。
总结记住一些打包的步骤,然后最好有一些C++的根本,有些观点可能比较难懂,比如指针,指针的解引用等操作。
我开始写demo的时候,也是碰着了各种坑。好在终极都逐一填完了。
这里是 畅哥聊技能 《让C++给node做技能加持》专题系列文章,更多内容,持续更新中,欢迎关注。
下期,我连续带大家入坑,看C++如果在electron开拓中给我们预留的坑吧。
全文完。