Класс Napi :: Object возвращает нестабильные результаты - PullRequest
0 голосов
/ 10 апреля 2020


В настоящее время я пишу библиотеку c ++, которая будет использоваться nodeJs с использованием node-addons-api . В библиотеке есть функция, которая принимает объект javascript в качестве входных данных этого формата:

{
  nclosest: 3,
  input: {
    riders: [
      {
        origin: {
          lat: 46.886,
          lng: 3.000002
        },
        destination: {
          lat: 47.88895,
          lng: 3.8876
        }
      }
    ],
    vehicles: [
      {
        _id: "_HxY87",
        location: {
          lat: 46.786,
          lng: 3.000002
        }
      }
    ]
  }
}

Библиотека анализирует ввод в классы c ++, используя Napi :: Object, находит транспортное средство nclosest для каждого гонщика на основе по формуле haversine и удалите отдаленные транспортные средства из списка, чтобы на выходе был объект, созданный также с использованием Napi::Object и имеющий тот же формат. Код для синтаксического анализатора из Js Object выглядит следующим образом:

Input parseFromJsInput(Napi::Object wrappedInput, Napi::Env env) {

    Napi::Array wrappedRiders = (wrappedInput.Get(Napi::String::New(env, "riders"))).As<Napi::Array>();
    vector<Rider> riders;
    for (int i = 0; i < (int)wrappedRiders.Length(); i++) {
        Napi::Object wrappedRider = ((Napi::Value)wrappedRiders[i]).As<Napi::Object>();
        Napi::Object wrappedOrigin = (wrappedRider.Get(Napi::String::New(env, "origin"))).As<Napi::Object>();
        double p_lat = (wrappedOrigin.Get(Napi::String::New(env, "lat"))).As<Napi::Number>();
        double p_lng = (wrappedOrigin.Get(Napi::String::New(env, "lng"))).As<Napi::Number>();
        Napi::Object wrappedDestination = (wrappedRider.Get(Napi::String::New(env, "destination"))).As<Napi::Object>();
        double d_lat = (wrappedDestination.Get(Napi::String::New(env, "lat"))).As<Napi::Number>();
        double d_lng = (wrappedDestination.Get(Napi::String::New(env, "lng"))).As<Napi::Number>();
        riders.push_back(Rider(p_lng, p_lat, d_lng, d_lat));
    }

    Napi::Array wrappedVehicles = (wrappedInput.Get(Napi::String::New(env, "vehicles"))).As<Napi::Array>();
    vector<Vehicle> vehicles;
    for (int i = 0; i < (int)wrappedVehicles.Length(); i++) {
        Napi::Object wrappedVehicle = ((Napi::Value)wrappedVehicles[i]).As<Napi::Object>();
        Napi::Object wrappedLocation = (wrappedVehicle.Get(Napi::String::New(env, "location"))).As<Napi::Object>();
        double lat = (wrappedLocation.Get(Napi::String::New(env, "lat"))).As<Napi::Number>();
        double lng = (wrappedLocation.Get(Napi::String::New(env, "lng"))).As<Napi::Number>();
        vehicles.push_back(Vehicle(lng, lat));
    }

    Input input = Input(vehicles, riders);
    return input;
};

А код синтаксического анализатора для Js объекта:

Napi::Object parseToJsInput(Input in, Napi::Env env) {
    Napi::Object inputObject = Napi::Object::New(env);

    Napi::Array ridersObject = Napi::Array::New(env);
    for (int i = 0; i < (int)in.riders.size(); i++) {
        Rider r = in.riders[i];
        Napi::Object riderObject = Napi::Object::New(env);
        Napi::Object originObject = Napi::Object::New(env);
        originObject.Set(Napi::String::New(env, "lat"), Napi::Number::New(env, r.p_lat));
        originObject.Set(Napi::String::New(env, "lng"), Napi::Number::New(env, r.p_lng));
        riderObject.Set(Napi::String::New(env, "origin"), originObject);
        Napi::Object destinationObject = Napi::Object::New(env);
        destinationObject.Set(Napi::String::New(env, "lat"), Napi::Number::New(env, r.d_lat));
        destinationObject.Set(Napi::String::New(env, "lng"), Napi::Number::New(env, r.d_lng));
        riderObject.Set(Napi::String::New(env, "destination"), destinationObject);
        ridersObject.Set(Napi::Number::New(env, i), riderObject);
    }
    inputObject.Set(Napi::String::New(env, "riders"), ridersObject);

    Napi::Array vehiclesObject = Napi::Array::New(env);
    for (int i = 0; i < (int)in.vehicles.size(); i++) {
        Napi::Object vehicleObject = Napi::Object::New(env);
        Napi::Object locationObject = Napi::Object::New(env);
        locationObject.Set(Napi::String::New(env, "lat"), Napi::Number::New(env, v.lat));
        locationObject.Set(Napi::String::New(env, "lng"), Napi::Number::New(env, v.lng));
        vehicleObject.Set(Napi::String::New(env, "location"), locationObject);
        vehiclesObject.Set(Napi::Number::New(env, i), vehicleObject);
    }
    inputObject.Set(Napi::String::New(env, "vehicles"), vehiclesObject);

    return inputObject;
}

И библиотечный метод следующим образом:

Napi::Value filterInputSync(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    Napi::HandleScope scope(env);
        int length = info.Length();
    if (length != 1 || !info[0].IsObject()) {
       Napi::TypeError::New(env, "Typed error").ThrowAsJavaScriptException();
    }
    Napi::Object wrappedInstance = info[0].As<Napi::Object>();
    int nclosest = (wrappedInstance.Get("nclosest")).As<Napi::Number>();
    Napi::Object wrappedInput = (wrappedInstance.Get("input")).As<Napi::Object>();
    Input input = parseFromJsInput(wrappedInput, env);
    Input filteredInput = doFilter(input, nclosest);
    return parseToJsInput(filteredInput, env);
}

Проблема в том, что когда я запускаю код, результаты для больших экземпляров часто бывают правильными, но иногда я получаю непредсказуемые результаты, например, вместо этого я получаю в результате число или поврежденную строку объекта создан. Любые предложения о том, что вызывает это непредсказуемое поведение.
Заранее спасибо.

...