2016-07-28 47 views
1

我目前正在使用他們的C++/v8系統爲NodeJS編寫一個本地插件,並試圖從Javascript編寫一個數組到C++,並稍後檢索它。每當我嘗試從數組中檢索一個值並將其返回時,它會返回一個空數組 - 正如我最近潛入C++中一樣,我不確定這是我的誤解指針/ C++基礎知識還是NodeJS C++交互。通過nan傳遞數組返回undefined當試圖檢索

我的文件如下:

functions.cc

#include "functions.h" 
#include <node.h> 
#include <nan.h> 

using namespace std; 
using namespace v8; 

NAN_METHOD(nothing) { 
} 

NAN_METHOD(aString) { 
    info.GetReturnValue().Set(Nan::New("This is a thing.").ToLocalChecked()); 
} 

NAN_METHOD(aBoolean) { 
    info.GetReturnValue().Set(false); 
} 

NAN_METHOD(aNumber) { 
    info.GetReturnValue().Set(1.75); 
} 

NAN_METHOD(anObject) { 
    v8::Local<v8::Object> obj = Nan::New<v8::Object>(); 
    Nan::Set(obj, Nan::New("key").ToLocalChecked(), Nan::New("value").ToLocalChecked()); 
    info.GetReturnValue().Set(obj); 
} 

NAN_METHOD(anArray) { 
    v8::Local<v8::Array> arr = Nan::New<v8::Array>(3); 
    Nan::Set(arr, 0, Nan::New(1)); 
    Nan::Set(arr, 1, Nan::New(2)); 
    Nan::Set(arr, 2, Nan::New(3)); 
    info.GetReturnValue().Set(arr); 
} 

NAN_METHOD(callback) { 
    v8::Local<v8::Function> callbackHandle = info[0].As<v8::Function>(); 
    Nan::MakeCallback(Nan::GetCurrentContext()->Global(), callbackHandle, 0, 0); 
} 

// Wrapper Impl 

Nan::Persistent<v8::Function> MyObject::constructor; 

NAN_MODULE_INIT(MyObject::Init) { 
    v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New); 
    tpl->SetClassName(Nan::New("MyObject").ToLocalChecked()); 
    tpl->InstanceTemplate()->SetInternalFieldCount(1); 

    //Nan::SetPrototypeMethod(tpl, "plusOne", PlusOne); 
    Nan::SetPrototypeMethod(tpl, "getArr", arrY); 
    Nan::SetPrototypeMethod(tpl, "PassArray", passArray); 
    Nan::SetPrototypeMethod(tpl, "setArray", SetArray); 

    constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked()); 
    Nan::Set(target, Nan::New("MyObject").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); 
} 

MyObject::MyObject(v8::Local<v8::Array> value) : value_(value) { 
} 

MyObject::~MyObject() { 
} 

NAN_METHOD(MyObject::New) { 
    if (info.IsConstructCall()) { 
    v8::Local<v8::Array> arr = Nan::New<v8::Array>(); 
    v8::Local<v8::Array> value = v8::Handle<v8::Array>::Cast(arr); 
    MyObject *obj = new MyObject(value); 
    obj->Wrap(info.This()); 
    info.GetReturnValue().Set(info.This()); 
    } else { 
    const int argc = 1; 
    v8::Local<v8::Value> argv[argc] = {info[0]}; 
    v8::Local<v8::Function> cons = Nan::New(constructor); 
    info.GetReturnValue().Set(cons->NewInstance(argc, argv)); 
    } 
} 

// NAN_METHOD(MyObject::PlusOne) { 
// MyObject* obj = Nan::ObjectWrap::Unwrap<MyObject>(info.This()); 
// obj->value_ += 1; 
// info.GetReturnValue().Set(obj->value_); 
// } 

NAN_METHOD(MyObject::SetArray){ 
    Nan::HandleScope scope; 
    vector<string> result; 
    Handle<Value> val; 
    Local<Array> arr = Nan::New<Array>(); 
    MyObject* obj = ObjectWrap::Unwrap<MyObject>(info.Holder()); 

    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(obj->value_); 
} 

NAN_METHOD(MyObject::arrY){ 
    MyObject* obj = ObjectWrap::Unwrap<MyObject>(info.Holder()); 
    info.GetReturnValue().Set(Local<Array>::Cast(obj->value_)); 
} 

NAN_METHOD(MyObject::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); 
     } 
    } 
    MyObject* obj = Nan::ObjectWrap::Unwrap<MyObject>(info.This()); 
    obj->value_ = arr; 
    info.GetReturnValue().Set(obj->value_); 
} 

functions.h

#ifndef NATIVE_EXTENSION_GRAB_H 
#define NATIVE_EXTENSION_GRAB_H 

#include <nan.h> 

// Example top-level functions. These functions demonstrate how to return various js types. 
// Implementations are in functions.cc 

NAN_METHOD(nothing); 
NAN_METHOD(aString); 
NAN_METHOD(aBoolean); 
NAN_METHOD(aNumber); 
NAN_METHOD(anObject); 
NAN_METHOD(anArray); 
NAN_METHOD(callback); 

// Example with node ObjectWrap 
// Based on https://nodejs.org/api/addons.html#addons_wrapping_c_objects but using NAN 
class MyObject : public Nan::ObjectWrap { 
    public: 
    static NAN_MODULE_INIT(Init); 

    private: 
    explicit MyObject(v8::Local<v8::Array> value); 
    ~MyObject(); 

    static NAN_METHOD(New); 
    static NAN_METHOD(PlusOne); 
    static NAN_METHOD(SetArray); 
    static NAN_METHOD(arrY); 
    static NAN_METHOD(passArray); 

    static Nan::Persistent<v8::Function> constructor; 
    v8::Local<v8::Array> value_; 
}; 

#endif 

index.js

var NativeExtension = require('bindings')('NativeExtension'); 
module.exports = NativeExtension; 


console.log(NativeExtension.aString()); 

var obj = NativeExtension.MyObject([1,2,3]); 
console.log(NativeExtension.aString()); 
console.log(obj.PassArray([1, 1, 3])); 
console.log(obj.getArr()); 
console.log(obj.setArray()) 

爲了測試代碼是肯定不是幹,它是基於upo n通過github which can be found here提供的nan-boilerplate代碼的非剝離版本。

在重讀自己的代碼我可以肯定地告訴大家,我的方法命名爲,所以PassArr應該設置一個數組,getArr應該返回由「PassArr」通過陣列。 。SetArray,是我留在

要重申一個hackish的嘗試,我試圖實現的功能是:

Javascript Array -> C++ variable 
C++ variable -> Javascript Array 

但目前功能不堅持我的變量。運行index.js的結果如下:

This is a thing. 
This is a thing. 
[ 1, 1, 3 ] 
Console { 
    log: [Function: bound ], 
    info: [Function: bound ], 
    warn: [Function: bound ], 
    error: [Function: bound ], 
    dir: [Function: bound ], 
    time: [Function: bound ], 
    timeEnd: [Function: bound ], 
    trace: [Function: bound trace], 
    assert: [Function: bound ], 
    Console: [Function: Console] } 
[] 
+0

@ simon-p-r感謝編輯 - 完全錯過了那個標籤 –

+1

不用擔心@ N.J.Dawson –

回答

1

優於從不遲到......這裏有兩個問題:

首先是MyObject::value_是當地的手柄。它應該是一個持久的句柄,你需要在~MyObject()中重置,否則它會泄漏。

第二個問題是MyObject::passArray中的數組arr的長度爲0,您應該使用正確的長度構造它。

+0

我不再在這個項目上工作,不再有代碼基礎可用,但我很感謝您的回答。我將你標記爲正確的答案,但我無法驗證這一點,因爲任何人稍後都會遇到此問題。 –

+1

謝謝。我認爲情況可能如此,但也認爲答案可能對其他人有幫助。 –