2016-10-17 5 views
1

J'ai une bibliothèque source sur C++ et je veux l'utiliser sur mon application Node.js. Pour apprendre comment cela fonctionne, j'utilise node-gyp pour compiler du code C++, qui a 2 fonctions simples pour calculer la somme de contrôle (crc16 et crc16Two).Сonversion array dans node.js avec node-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 fonctionne très bien, je le résultat correct, mais quand je compile CRC16 avec node-gyp rebuild je erreurs:

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

Ici binding.gyp:

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

et le code sur 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)); 

Pouvez-vous dire comment le réparer? Je pense que je fais quelque chose de mal.

Répondre

0

Je suis très confus au sujet de cette ligne:

crc ^= data++ << 8; 
données

est effectivement un:

v8::Local <v8 :: Array> * 

Mais du documentation, il n'y a aucune mention d'une mise en œuvre de l'opérateur < < sur elle. L'erreur est justifiée pour moi. et un peu de décalage semble étrange, êtes-vous vraiment sûr de vouloir le faire?

Aussi, juste supérieure de ce que vous faites:

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

Au moment où vous écrivez des données * = jsArray, les données sont un pointeur non initialisée, l'écriture des données * seront faire votre plantage du programme.

+0

Oh, j'ai compris. Puis-je convertir jsArray en tableau C++ typique pour travailler avec? Ou ce n'est pas possible. – japskiddin

+0

J'essaye de faire quelque chose comme ceci:

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(); } }
Cela fonctionne sans erreur, mais pendant le test, chaque fois que je reçois un nouveau résultat avec les mêmes données. – japskiddin