Delphi вызывает методы JNI с переменным списком аргументов

Используя модуль Jni api Embarcadero, как можно предоставить списки переменных-переменных для методов JNI, которые в этом нуждаются? Например, метод CallStaticObjectMethodV () объекта JNINativeInterface (листинг 1) имеет последний параметр типа va_list, который должен инкапсулировать переменный список аргументов. В коде C ++ (листинг 2), который вызывает этот метод, сигнатура метода помечается как varargs, что удивительно, поскольку в модуле Delphi AndroidApi.Jni отсутствует декорация varargs.

Как вы должны построить параметр Args для достижения того же самого в Delphi? Моя попытка, показанная в листинге 3, не работает.

Листинг 1: Извлечение из модуля Androidapi.Jni, слегка адаптированное для платформы Windows (изменено cdecl для stdcall)
JNINativeInterface = packed record
    ...
    CallStaticObjectMethod : function(Env: PJNIEnv; AClass: JNIClass; MethodID: JNIMethodID): JNIObject; stdcall;
    CallStaticObjectMethodV: function(Env: PJNIEnv; AClass: JNIClass; MethodID: JNIMethodID; Args: va_list  ): JNIObject; stdcall;
    CallStaticObjectMethodA: function(Env: PJNIEnv; AClass: JNIClass; MethodID: JNIMethodID; Args: PJNIValue): JNIObject; stdcall;
Листинг 2: Пример того, как он вызывается из C ++

Листинг 2 был извлечен из библиотеки Saxon / C.

XdmValue * SaxonProcessor::parseFile(const char* source){

    jmethodID mID = (jmethodID)env->GetStaticMethodID(saxonCAPIClass, "xmlParseFile", "(Lnet/sf/saxon/s9api/Processor;Ljava/lang/String;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;");
    if (!mID) {
    cerr<<"\nError: MyClassInDll "<<"xmlParseFile()"<<" not found"<<endl;
        return NULL;
    }
   jobject xdmNodei = env->CallStaticObjectMethod(saxonCAPIClass, mID, proc, env->NewStringUTF(cwd.c_str()),  env->NewStringUTF(source));
     if(exceptionOccurred()) {
       exception= checkForException(env, saxonCAPIClass, NULL);
     } else {
    XdmValue * value = new XdmValue(xdmNodei);
    value->setProcessor(this);
    return value;
   }
   return NULL;
}
Листинг 3: Моя попытка перевести листинг 2 в Delphi
var
  mID: JNIMethodID;
  xdmNodei: JNIObject;
  Str1, Str2: JNIString;
  Hold1, Hold2: TBytes;
  ArgsAsList: va_list;
  Data: TBytes;
  Sz: integer;
begin
  mID := FJNIEnv.GetStaticMethodID( Fpenv, FsaxonCAPIClass, 'xmlParseFile',
    '(Lnet/sf/saxon/s9api/Processor;Ljava/lang/String;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;');
  Str1 := FJNIEnv.NewStringUTF( Fpenv, String_to_MarshaledAString( Fcwd  , Hold1));
  Str2 := FJNIEnv.NewStringUTF( Fpenv, String_to_MarshaledAString( Source, Hold2));
  Sz := SizeOf( JNIString);
  SetLength( Data, 3 * Sz);
  FillChar( Data[0], Length( Data), 0);
  Move( Str1, Data[0], Sz);
  Move( Str1, Data[Sz], Sz);
  ArgsAsList := va_list( @Data[0]);
  xdmNodei := FJNIEnv.CallStaticObjectMethodV( Fpenv, FsaxonCAPIClass, mID, ArgsAsList);
Что также не сработало

Я также попытался переопределить тип метода, который должен быть декорирован с помощью varargs, и реализовать varargs, передаваемые с помощью ассемблера, используя метод, описанный в этих решениях. Они не работали. (Нарушение доступа).

Как функция с 'varargs' может извлечь содержимое стека?Delphi "массив const" для "varargs"Немного больше информации

Целевая платформа - Win32. Я сделал копию AndroidApi.jni.pas для Windows (WinApi.jni.pas). Я только что изменил украшения cdecl для stdcall. stdcall верен, и я могу использовать модуль, чтобы запустить JavaVM и делать другие вещи JNI. Embaracedero не помечает CallStaticObjectMethodV () как переменную, но, возможно, это ошибка?

Обновление: окончательное решение

БлагодаряДжонатан Ревуски JNI WrapperЯ разработал рабочее решение ...

Код, который работает, это ..

function TSaxonProcessor.parseFile( const Source: string): TXdmValue;
var
  mID: JNIMethodID;
  xdmNodei: JNIObject;
  Str1, Str2: JNIString;
  Hold1, Hold2: TBytes;
  Data: TArray<JNIString>;
begin
  mID := FJNIEnv.GetStaticMethodID( Fpenv, FsaxonCAPIClass, 'xmlParseFile',
    '(Lnet/sf/saxon/s9api/Processor;Ljava/lang/String;Ljava/lang/String;)Lnet/sf/saxon/s9api/XdmNode;');
  Str1 := FJNIEnv.NewStringUTF( Fpenv, String_to_MarshaledAString( Fcwd  , Hold1));
  Str2 := FJNIEnv.NewStringUTF( Fpenv, String_to_MarshaledAString( Source, Hold2));
  SetLength( Data, 3);
  Data[0] := FProc;
  Data[1] := Str1;
  Data[2] := Str2;
  xdmNodei := FJNIEnv.CallStaticObjectMethodV( Fpenv, FsaxonCAPIClass, mID, @Data[0]);
end;

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

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