В настоящее время я пишу библиотеку 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);
}
Проблема в том, что когда я запускаю код, результаты для больших экземпляров часто бывают правильными, но иногда я получаю непредсказуемые результаты, например, вместо этого я получаю в результате число или поврежденную строку объекта создан. Любые предложения о том, что вызывает это непредсказуемое поведение.
Заранее спасибо.