O Delphi chama métodos JNI com lista de argumentos variáveis

Usando a unidade api Jni da Embarcadero, como um argumento variável é fornecido para os métodos JNI que o exigem? Por exemplo, o método CallStaticObjectMethodV () do JNINativeInterface (listagem 1) possui um último parâmetro do tipo va_list, que deve encapsular uma lista variável de argumentos. No código C ++ (listagem 2) que chama esse método, a assinatura do método é marcada como varargs, o que é surpreendente, porque não há decoração de varargs na unidade AndroidApi.Jni do Delphi.

Como você deve construir o parâmetro Args para obter a mesma coisa no Delphi? Minha tentativa, mostrada na listagem 3, não funciona.

Listagem 1: Extrair da unidade Androidapi.Jni, ligeiramente adaptado para a plataforma Windows (alterado cdecl para 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;
Listagem 2: Um exemplo de como é chamado em C ++

A Listagem 2 foi extraída da biblioteca 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;
}
Listagem 3: Minha tentativa de traduzir a listagem 2 em 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);
O que também não funcionou

Também tentei redeclarar o tipo de método a ser decorado com varargs e implementar os varargs que passam com o mês de dezembro, usando o método descrito nessas soluções. Eles não funcionaram. (Violação de acesso).

Como uma função com 'varargs' recupera o conteúdo da pilha?Delphi "array de const" para "varargs"Um pouco mais de informação

A plataforma de destino é o Win32. Fiz uma cópia do AndroidApi.jni.pas para Windows (WinApi.jni.pas) Acabei de alterar as decorações do cdecl para stdcall. O stdcall está correto e posso usar a unidade para iniciar o JavaVM e executar outras tarefas JNI. Embaracedero não marca CallStaticObjectMethodV () como varargs, mas talvez isso seja um erro?

Atualização: A solução final

Graças aWrapper JNI de Jonathan Revusky, Elaborei uma solução funcional ...

O código que funciona é ..

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;

questionAnswers(1)

yourAnswerToTheQuestion