I'm working with the Node.js N-API and I'm making a little wrapper that will make exporting C++ functions easy.
template<class T, class... Targs> napi_value Api::create(const char* name, T (* const cb)(Targs...))
{
// creates JavaScript function that will call cbProxy<> when called
return create(name, cbProxy<T, Targs...>, cb);
}
template<class T, class... Targs> napi_value Api::cbProxy(const napi_env env, const napi_callback_info info)
{
// number of arguments
size_t count = sizeof...(Targs);
ApiValue args[count];
T (* cb)(Targs...);
// retrieve arguments and callback
if (!Api::getParams(env, info, args, count, &cb))
return nullptr;
T ret = cb(Api::getValue<Targs>(&args[--count])...);
return Api(env).create(ret);
}
template<> bool Api::getValue(ApiValue* value)
{
return value->toBool();
}
template<> double Api::getValue(ApiValue* value)
{
return value->toDouble();
}
template<> int32_t Api::getValue(ApiValue* value)
{
return value->toInt32();
}
The idea is to call api.create("TestFunction", testFn);
which will return a JS function.
When it's called, it will call Api::cbProxy<>
which converts the JS parameters to the equivalent C++ types with Api::getValue<T>()
and calls testFn
(cb).
Lets say testFn
has the following signature: int testFn(bool bVal, double dVal)
The line T ret = cb(Api::getValue<Targs>(&args[--count])...);
will expand to
int ret = cb(Api::getValue<bool>(&args[--count]),
Api::getValue<double>(&args[--count]));
Which works 100% fine, but it triggers a compiler warning. I'm a bit of a novice regarding C++, so I'm looking for a better way to write this.
Basically I want to traverse the array args
and the list of type parameters Targs
at once.
Just to clarify: The --count
in the expanded function call triggers the following warning:
warning: operation on ‘count’ may be undefined [-Wsequence-point]