How to pass the paramater of Node.js or io.js into native C/C++ function.

How to pass the paramater of Node.js or io.js into native C/C++ function?

Here's  how I found:

http://www.puritys.me/docs-blog/article-286-How-to-pass-the-paramater-of-Node.js-or-io.js-into-native-C-C++-function..html

In order to be compatible for any version of Node.js and io.js. We can use the Nan library: " https://github.com/nodejs/nan "

If you have used the old version of Nan and want to upgrade it, you should do the following changes.

Nan Conversion
// The Legacy Nan example
unsigned int microSeconds = args[0]->Uint32Value();
NanReturnValue(NanNew<String>("text"));
NanReturnThis();
Handle<Value> key = Nan::New<String>("DOMDocument");
NODE_SET_PROTOTYPE_METHOD(constructor, "load", load);
 
// The latest Nan example
unsigned int microSeconds = info[0]->Uint32Value();
info.GetReturnValue().Set(Nan::New<String>("text"));
info.GetReturnValue().Set(info.This());
Handle<Value> key = Nan::New<String>("DOMDocument").ToLocalChecked();
Nan::SetPrototypeMethod(constructor, "load", load);

After that here has more variable conversions for you.

Brief
String::Utf8Value cmd(info[0]);
unsigned int len = info[0]->Uint32Value();
bool isBinary = info[0]->BooleanValue();
 
Local<Object> bufferObj = info[1]->ToObject();
char* msg = Buffer::Data(bufferObj);
Pass a JavaScript string into native C/C++ with Nan library

Example
#include <iostream>                                                                                                                                 
#include <node.h>
#include <nan.h>
using namespace std;
using namespace v8;
using namespace nan;
 
NAN_METHOD(name)
{
    Nan::HandleScope scope;
    String::Utf8Value cmd(info[0]);
    string s = string(*cmd);
    info.GetReturnValue().Set(Nan::New<String>(s.c_str()).ToLocalChecked());
}
Pass a JavaScript integer into native C/C++ with Nan library

Example
#include <iostream>                                                                                                                                 
#include <node.h>
#include <nan.h>
using namespace std;
using namespace v8;
using namespace nan;
 
NAN_METHOD(name)
{
    Nan::HandleScope scope;
    unsigned int len = info[0]->Uint32Value();
    info.GetReturnValue().Set(Nan::New<Integer>(len).ToLocalChecked());
}
Pass a Node.js binary string into native C/C++ with Nan library

When you have Unicode String which include some un-English letters. Then you must pass the value in a binary format.

Example
#include <iostream>                                                                                                                                 
#include <node.h>
#include <nan.h>
using namespace std;
using namespace v8;
using namespace nan;
 
NAN_METHOD(sendData)
{
    Local<Object> bufferObj = info[0]->ToObject();
    unsigned int len = info[1]->Uint32Value();
    char* msg = Buffer::Data(bufferObj);
 
    info.GetReturnValue().Set(Nan::New<String>(msg, len).ToLocalChecked());
    // You can not use strlen(msg). Because it is a binary not a string. The end of  string is a null byte and  the end of binary data is not null.
}
Node.js call native function.
//
    var data = "The data include some UTF8 encoding string.";
    length = Buffer.byteLength(data); //UTF8 length
    var buf = new Buffer(length);
    buf.write(data, 0, 'UTF8');
    native.sendData(buf, length);
Pass a JavaScript array into native C/C++ with Nan library

Pass array and return array
NAN_METHOD(passArray) {
    Nan::HandleScope scope;
    vector<string> result;
    Handle<Value> val;
    Local<Array> arr = Nan::New<Array>();
 
    if (info[0]->IsArray()) {
      Handle<Array> jsArray = Handle<Array>::Cast(info[0]);
      for (unsigned int i = 0; i < jsArray->Length(); i++) {
        val = jsArray->Get(i);
        result.push_back(string(*String::Utf8Value(val)));
        Nan::Set(arr, i, val);
      }
    }
    info.GetReturnValue().Set(arr);
}
Pass a function into native C/C++ with Nan library

callback.cc
#include <node.h>
#include <nan.h>
using namespace node;
using namespace v8;
 
NAN_METHOD(runCallback) {
    Nan::HandleScope scope;
    Local<Object> context = Local<Object>::Cast(info[0]);
    Handle<Value> param1 = Handle<Value>::Cast(info[1]);
    Local<v8::Function > callback_handle = Local<v8::Function>::Cast(info[2]);
 
    Local<Value> argv[1] = { param1 };
    Nan::MakeCallback(context, callback_handle, 1, argv);
    info.GetReturnValue().SetUndefined();
}
 
void  init (Handle<Object> target){
    Nan::HandleScope scope;
    Nan::SetMethod(target, "runCallback", runCallback);
}
 
NODE_MODULE(obj, init)
After the success of compiling, then you can write a Node.js code to test the native shared object.

call.js
var native = require('./build/Release/callback.node');
 
function person() {
    this.age = 18;
}
 
person.prototype.run = function () {console.log("My age is " + this.age);};
 
var p = new person();
p.age = 20;
 
native.runCallback(
    p, "the value",
    function (param1) {
        this.run();
        console.log("param1 = " + param1);
    }
);
How to return "this" context

Example
info.GetReturnValue().Set(info.This());
Examples

You can see more examples at my Node.js library called phplike.

https://github.com/puritys/nodejs-phplike/tree/master/src/nodeExt


Old Version of Nan library

Please migrate your legacy code to support the latest version of Nan library as soon as possibile.
The following is only used for the old version of Node.js 0.10.x. Node.js have already upgrade the latest JavaScript V8 engine. And we will used the new code to write a Node.js addon as stated previous paragraph.


Pass a JavaScript string into C/C++

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include <string>
using namespace std;
using namespace v8;
 
Handle<Value> passString(const Arguments& args)
{
    String::Utf8Value cmd(args[0]);
    string s = string(*cmd);
    return String::New(s.c_str());
   //Integer::New(1)
}
Pass a JavaScript integer into C/C++

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include <string>
using namespace std;
using namespace v8;
Handle<Value> passInt(const Arguments& args)
{
    unsigned int microSeconds = args[0]->Uint32Value(); 
 
    return True();
}
Pass a JavaScript array into C/C++

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include "node.h"
#include <string>
#include <vector>
using namespace std;
using namespace v8;
using namespace node;
 
Handle<Value> passArray(const Arguments& args) {
    vector<string> result;
    Handle<Value> val;
    if (args[0]->IsArray()) {
      Handle<Array> jsArray = Handle<Array>::Cast(arg[0]);
      for (int i = 0; i < jsArray->Length(); i++) {
        val = jsArray->Get(Integer::New(i)); 
        result.push_back(string(*String::Utf8Value(val)));
      }
    }
 
    return  String::New("success");
}
Pass a JavaScript object into C/C++

Here is a example to get the value from a specific keyname and if this value is a function , we convert it into the variable type of v8 function Handle.

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include "node.h"
#include <string>
using namespace std;
using namespace v8;
using namespace node;
 
Handle<Value> passObject(const Arguments& args) {
 
  if (args[0]->IsObject()) {
      Handle<Object> object = Handle<Object>::Cast(args[0]);
      Handle<Value> fieldValue = object->Get(String::New("key1"));
      Handle<Value> callback = object->Get(String::New("callback"));
      if (callback->IsFunction()) {
          Handle<Function> fn = Handle<Function>::Cast(callback);
      }
  }
}


Using the forloop to get every key and value from the object.

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include "node.h"
#include <string>
#include <map>
using namespace std;
using namespace v8;
using namespace node;
 
Handle<Value> passObject(const Arguments& args) {
  map<string, string> options;
  int i,n;
   if (args[0]->IsObject()) {
        jsOptions = Handle<Object>::Cast(args[0]);
        propertyNames = jsOptions->GetPropertyNames();
        n = propertyNames->Length();
        for (i = 0; i < n ; i++) {
            Handle<Value>  b = propertyNames->Get(Integer::New(i));
            string c = string(*String::Utf8Value(b));
            Handle<Value>  v = jsOptions->Get(b);
            options[c] = string(*String::Utf8Value(v));
        }   
 
    }  
}
Pass a JavaScript boolean into C/C++

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include <string>
using namespace std;
using namespace v8;
Handle<Value> passInt(const Arguments& args)
{
    bool = args[0]->BooleanValue(); 
 
    return bool;
}
Pass a JavaScript binary into C/C++ char*

Example
#include <iostream>                                                                                                                                 
#include "v8.h"
#include <string>
using namespace std;
using namespace v8;
Handle<Value> passBinary(const Arguments& args)
{
    Local<Object> bufferObj = args[1]->ToObject();
    char* msg = Buffer::Data(bufferObj);
    
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值