Оболочка вызывающей функции C ++ с использованием расширения типов пакетов variadic

Я изучил множество шаблонов с расширением пакета variadic, но все же не могу собрать все статьи, которые нашел здесь, чтобы достичь своей цели. Пожалуйста, примите мои извинения за то, что, возможно, излишним. Я связан с некоторыми API, и я связан с некоторыми сигнатурами функций, как здесь:

static bool WrapperFunction(JSContext *cx, unsigned argc, JS::Value *vp)

Я пытаюсь обернуть объекты и функции для использования в JavaScript под SpiderMonkey. Чтобы интегрировать некоторый C API, должны быть реализованы оболочки для данных объекта и методы оболочки для некоторого объекта.

Мое решение привело меня к следующей логике оболочки, чтобы можно было вызывать методы с несколькими аргументами, но я не знаю, как этого добиться:

    template<typename jsType, typename jsReturnType, typename MethodType, MethodType Method, typename... jsParamType>
static bool VAMethodRet(JSContext *cx, unsigned argc, JS::Value *vp)
{
    JS::CallArgs args = CallArgsFromVp(argc, vp);

    jsReturnType::PrivateType result = jsReturnType::PrivateTypeDefaultValue();

Здесь начинаются мои проблемы.

Первый шаг. Разверните ... jsParamType ... pack с вызовом метода для каждого jsParamType, чтобы создать экземпляр объекта класса-оболочки для сопоставления соответствующего аргумента из аргументов, чтобы подготовить вызов функции API C.

Другими словами, jsParamType сообщает тип, который он переносит, чтобы он мог извлечь объект типа C для каждого параметра, передаваемого в функцию C API.

Первый jsParamType соответствует args [0], второй jsParamType соответствует args1 и т.д., до последнего jsParamType, который соответствует args [argc].

Можно получить меньше элементов в аргументах, чем sizeof ... jsParamType, в этом случае базовый объект C должен быть инициализирован со значением по умолчанию.

Мета-информация о параметрах или обертках объектов уже достигается статическими методами (например, jsParamType :: jsType :: PrivateTypeDefaultValue ()).

В конце концов, расширенный пакет должен быть массивом или вектором разнородных объектов.

Функция сопоставления должна быть шаблонной, основанной на jsParamType, но также получать индекс расширенного пакета переменных и локальную переменную args, чтобы получить правильный объект для анализа - вот моя первая проблема:

Как передать индекс в метод?

Я пытался получить вдохновение отсюда, но я не могу заставить его работать:Вызов функции для каждого аргумента шаблона переменной и массива

Второй шаг, После этого я планирую использовать подобную технику здесь:Получить индекс аргумента при распаковке списка аргументов с помощью шаблонов Variadic чтобы вызвать функцию API C с правильными аргументами - возможно ли это?

Третий шаг, В конце, на основе статической функции jsParamType, называемой IsOut (), значения out обновят содержимое локальной переменной args, но это следует сделать снова, используя новое расширение, аналогичное первому шагу, чтобы вернуть некоторые значения с использованием информации о типе, присутствующей в элементах jsParamType.

Последнее, что нужно сделать, это установить возвращаемое значение, что тривиально.

Условные обозначения:jsType является типом структуры, содержащей указатель на функции C API, так как они сгруппированы поставщиком C API.jsReturnType это тип возвращаемого значения. (просто для справки здесь ...)метод метод C API, который должен быть вызванMethodType тип.

Пожалуйста, помогите мне написать такой код, так как я не могу заставить его работать. Я не прошу думать за меня и быть моим частным программистом. У меня просто нет опыта работы с этой частью препроцессора, я вижу много примеров, много ошибок бросков, или я не могу их расширить, чтобы достичь вышеуказанной функции. Спасибо.

РЕДАКТИРОВАТЬ 1

Спасибо за ответ,AndyG, Вот более или менее псевдокод:

    // *jsType* is a type of the struct containing the pointer to the C API functions, as these are grouped by the C API's provider.
    // *jsReturnType* is the return type. (just for reference here...)
    // *Method* is a C API method to be called, having the *MethodType* type.
    // The non-template part of the function signature is needed untouched by SpiderMonkey

    template<typename jsType, typename jsReturnType, typename MethodType, MethodType Method, typename... jsParamType>
static bool VAMethodRet(JSContext *cx, unsigned argc, JS::Value *vp)
{
    // get the collection of passed arguments (SpiderMonkey stuff), in args, each element accessible by index
    // argc is the number of parameters passed from javascript
    WrappersCollection args = GetCallArgsFromVp(argc, vp);

    jsReturnType::PrivateType result = jsReturnType::PrivateTypeDefaultValue(); // creates an instance of a return value wrapper to receive the return value later

    // 1. Match wrappers in the WrappersCollection against their types in order to get their C type values
    CDataCollection cdata = array or vector of heterogeneous objects (int, char*, structs etc.);
    for each (jsParamType in the variadic pack ...)
    {
         cdata[jsParamTypeIndex] = Match<jsParamType, jsParamTypeIndex>(args);
    }
    // the above should be done by expanding the pack somehow
    // with emphasis on checking if argc[jsParamTypeIndex] was passed actually, because it's possible to have jsParamTypeIndex > argc
    // I don't know how to do it otherwise, by matching some param types variadic pack against a variadic pack of data arguments with different number of elements

    // 2. Transform the cdata collection into a variadic parameters pack in order to pass them to the C function.
    // The amount of args is specified by the function
    result = CFunction(cdata...);

    // 3. Update returned data in *out* params in the collection of wrapper objects received in the first place
    // index of the param in pack is necessary again
    // due to the different number of elements in the param types variadic pack versus the variadic pack of data arguments
    for each (jsParamType in the variadic pack ...)
    {
         if (jsParamType::IsOUT())
         {
              cdata[jsParamTypeIndex] = MatchBack<jsParamType, jsParamTypeIndex>(args);
         }
    }

    // the rest of things to do
    MatchReturnValue(result);

    return true; // SpiderMonkey needs to know the success of the operation
}

Это более понятно?

Ответы на вопрос(1)

Ваш ответ на вопрос