2016-10-17 2 views
1

У меня есть исходная библиотека на C++, и я хочу использовать ее в приложении Node.js. Для того, чтобы узнать, как это работает, я использую node-gyp для компиляции кода на C++, у которого есть две простые функции для вычисления контрольной суммы (crc16 и crc16Two).Массив конверсии в node.js с узлом-gyp

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

    if (args.Length() < 2) { 
     // Throw an Error that is passed back to JavaScript 

     isolate->ThrowException(Exception::TypeError(
      String::NewFromUtf8(isolate, "Wrong number of arguments"))); 
     return; 
    } 

    uint32_t size = args[1]->Uint32Value(); 
    Local<Array> *data; 
    Local<Array> jsArray = Local<Array>::Cast(args[0]); 
    *data = jsArray; 

    uint16_t crc = 0xFFFF; 
    uint8_t i = 0; 

    while (size--) 
    { 
     crc ^= data++ << 8; 

     for (i = 0; i < 8; i++) 
      crc = crc & 0x8000 ? (crc << 1)^0x1021 : crc << 1; 
    } 

    Local<Number> num = Number::New(isolate, crc); 
    args.GetReturnValue().Set(num); 
} 

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

    // Check the number of arguments passed. 

    if (args.Length() < 2) { 
     // Throw an Error that is passed back to JavaScript 

     isolate->ThrowException(Exception::TypeError(
      String::NewFromUtf8(isolate, "Wrong number of arguments"))); 
     return; 
    } 
    // Check the argument types 

    if (!args[0]->IsNumber() || !args[1]->IsNumber()) { 
     isolate->ThrowException(Exception::TypeError(
      String::NewFromUtf8(isolate, "Wrong arguments"))); 
     return; 
    } 
    // Perform the operation 

    uint16_t v1 = args[0]->Uint32Value(); 
    uint16_t v2 = args[1]->Uint32Value(); 
    uint16_t crc = 0xFFFF; 
    uint8_t i = 0; 
    crc ^= v1 << 8; 
    for (i = 0; i < 8; i++) 
     crc = crc & 0x8000 ? (crc << 1)^0x1021 : crc << 1; 

    crc ^= v2 << 8; 
    for (i = 0; i < 8; i++) 
     crc = crc & 0x8000 ? (crc << 1)^0x1021 : crc << 1; 

    Local<Number> num = Number::New(isolate, crc); 
    args.GetReturnValue().Set(num); 
} 

Crc16Two работает отлично, у меня есть правильный результат, но когда я компилирую CRC16 с node-gyp rebuild у меня есть ошибки:

..\Crc.c (49): error C2296: <<: inadmissible, the left operand is "v8::Local <v8 :: Array> *" [C:\Users\dns\Desktop\Crc\build\addon.vcxproj] 

Здесь binding.gyp:

{ "targets": [{"target_name": "addon", "sources": [ "crc.cc" ], "include_dirs" : ["<!(node -e \"require('nan')\")"]}]} 

И код на Node.js:

var addon = require('bindings')('addon'); 
var buf = new Buffer([0,1,2,3,4,5,6,7,8,9]); 
console.log(addon.crc16(buf,10)); 
console.log(addon.crc16Two(32145, 1470)); 

Не могли бы вы рассказать, как это исправить? Я думаю, что я делаю что-то неправильно.

ответ

0

Я очень смущен об этой линии:

crc ^= data++ << 8; 

данные эффективно:

v8::Local <v8 :: Array> * 

Но из documentation, нет никакого упоминания о реализации < < оператора на нем. Ошибка для меня оправдана. и смещение бит на нем кажется странным, вы действительно уверены, что хотите это сделать?

Кроме того, только верхнее того, что вы делаете:

Local<Array> *data; 
Local<Array> jsArray = Local<Array>::Cast(args[0]); 
*data = jsArray; 

На данный момент вы пишете * данные = jsArray, данные представляет собой инициализирован указатель, писать * данные будет сделать ваш сбой программы.

+0

О, я понял. Можно ли преобразовать jsArray в типичный массив C++ для работы с ним? Или это невозможно. – japskiddin

+0

Я пытаюсь сделать что-то вроде этого:

Local jsArray = Local::Cast(args[0]); uint32_t size = args[1]->Uint32Value(); uint8_t *data = new uint8_t[size]; for (unsigned int i = 0; i < jsArray->Length(); i++) { if (jsArray->Has(i)) { *data = jsArray->Get(i)->Uint32Value(); } }
Он работает без ошибок, но во время теста каждый раз, когда я получаю новый результат с теми же данными. – japskiddin