2016-11-11 6 views
1

Я пытаюсь обернуть C++ объекты для использования в JavaScript согласно Node.js документации здесь: https://nodejs.org/api/addons.html#addons_wrapping_c_objectsКак использовать std :: string в C++ Addon для Node.js?

аддон будет строить без ошибок, и нормально работать, когда мой объект «AnObject» был только числовые атрибуты т.е. " int32_t age; ".

Когда я добавил атрибут «std :: string name;» в AnObject, «узел-лавочка Configure» работала, однако «узел-лавочка сборка» дала следующую ошибку:

Wills-MacBook-Pro:cppObjectWrapping willalley$ node-gyp build 
[...] 
In file included from ../personAddon.cc:3: 
../AnObject.h:24:21: error: implicit instantiation of undefined template 
'std::basic_string<char, std::char_traits<char>, 
     std::allocator<char> >' 
     std::string name; 
        ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs 
/MacOSX10.12.sdk/usr/include/c++/4.2.1/bits/stringfwd.h:56:11: note: 
     template is declared here 
    class basic_string; 
     ^
1 error generated. 
[...] 
Wills-MacBook-Pro:cppObjectWrapping willalley$ 

Вот мои объекты заголовок файла, где брошено ошибка, AnObject.h:

#pragma once 

    #include <node.h> 
    #include <node_object_wrap.h> 
    #include <string.h> 

    namespace demo { 

     class AnObject : public node::ObjectWrap { 
     public: 
      static void Init(v8::Local<v8::Object> exports); 

     private: 
      explicit AnObject(int32_t num = 19); 
      ~AnObject(); 

      static void New(const v8::FunctionCallbackInfo<v8::Value>& args); 
      static void setAge(const v8::FunctionCallbackInfo<v8::Value>& args); 
      static void getAge(const v8::FunctionCallbackInfo<v8::Value>& args); 
      static void setName(const v8::FunctionCallbackInfo<v8::Value>& args); 
      static void getName(const v8::FunctionCallbackInfo<v8::Value>& args); 
      static v8::Persistent<v8::Function> constructor; 
      int32_t age; 
      std::string name; 
     }; 

    } // namespace demo 

и если вам интересно, файл реализации AnObject.cc:

#include "AnObject.h" 
#include <string.h> 

namespace demo { 

    using v8::Context; 
    using v8::Function; 
    using v8::FunctionCallbackInfo; 
    using v8::FunctionTemplate; 
    using v8::Isolate; 
    using v8::Local; 
    using v8::Number; 
    using v8::Object; 
    using v8::Persistent; 
    using v8::String; 
    using v8::Value; 

    Persistent<Function> AnObject::constructor; 

    AnObject::AnObject(int32_t age_) : age(age_) { 
    } 

    AnObject::~AnObject() { 
    } 

    void AnObject::Init(Local<Object> exports) { 
     Isolate* isolate = exports->GetIsolate(); 

     // Prepare constructor template 
     Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); 
     tpl->SetClassName(String::NewFromUtf8(isolate, "AnObject")); 
     tpl->InstanceTemplate()->SetInternalFieldCount(1); 

     // Prototype 
     NODE_SET_PROTOTYPE_METHOD(tpl, "setAge", setAge); 
     NODE_SET_PROTOTYPE_METHOD(tpl, "setName", setName); 
     NODE_SET_PROTOTYPE_METHOD(tpl, "getAge", getAge); 
     NODE_SET_PROTOTYPE_METHOD(tpl, "getName", getName); 

     constructor.Reset(isolate, tpl->GetFunction()); 
     exports->Set(String::NewFromUtf8(isolate, "AnObject"), 
        tpl->GetFunction()); 
    } 

    void AnObject::New(const FunctionCallbackInfo<Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 

     if (args.IsConstructCall()) { 
      // Invoked as constructor: `new AnObject(...)` 
      int32_t value = args[0]->IsUndefined() ? 0 : args[0]->Int32Value();; 
      AnObject* obj = new AnObject(value); 
      obj->Wrap(args.This()); 
      args.GetReturnValue().Set(args.This()); 
     } else { 
      // Invoked as plain function `AnObject(...)`, turn into construct call. 
      const int argc = 1; 
      Local<Value> argv[argc] = { args[0] }; 
      Local<Context> context = isolate->GetCurrentContext(); 
      Local<Function> cons = Local<Function>::New(isolate, constructor); 
      Local<Object> result = 
      cons->NewInstance(context, argc, argv).ToLocalChecked(); 
      args.GetReturnValue().Set(result); 
     } 
    } 

    void AnObject::setAge(const FunctionCallbackInfo<Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 
     AnObject* obj = ObjectWrap::Unwrap<AnObject>(args.Holder()); 
     if (args[0]->IsInt32()){ 
      obj->age = args[0]->Int32Value(); 
      args.GetReturnValue().Set(Number::New(isolate, obj->age)); 
     } 
    } 

    void AnObject::setName(const v8::FunctionCallbackInfo<v8::Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 
     AnObject* obj = ObjectWrap::Unwrap<AnObject>(args.Holder()); 

     if (args[0]->isString()) { 
      std::string input(*v8::String::Utf8Value(args[0]->ToString())); 
      obj->name = input; 
      args.GetReturnValue().Set(Number::New(isolate, obj->name)); 
     } 
    } 

    void AnObject::getAge(const FunctionCallbackInfo<Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 
     AnObject* obj = ObjectWrap::Unwrap<AnObject>(args.Holder()); 
     args.GetReturnValue().Set(Number::New(isolate, obj->age)); 
    } 

    void AnObject::getName(const FunctionCallbackInfo<Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 
     AnObject* obj = ObjectWrap::Unwrap<AnObject>(args.Holder()); 
     v8::Local<v8::String> output = v8::String::NewFromUtf8(isolate, name.cstr()); 
     args.GetReturnValue().Set(Number::New(isolate, output)); 
    } 

} // namespace demo 
+0

выглядит ваш "компилятор" не знает о классе станд :: строки из C++ стандартная библиотека ... – Macmade

+0

Возможно, посмотрите 'v8 :: String' – Macmade

+0

Не редактируйте решение в своем вопросе. Вместо этого ответьте на свой вопрос. – dorukayhan

ответ

0

лицо ладони достойным решением я нашел:

изменение:

#include <string.h> 

к:

#include <string> 

в обоих AnObject.h и AnObject.cc

 Смежные вопросы

  • Нет связанных вопросов^_^