Ještě jednou Delphi a Java, tentokrát v XE2 64bit

vložil Karel 30. července 2012 21:45

Před časem jsem psal o propojení projektů v Javě a Delphi prostřednictvím rozhraní JNI (unit JNI.pas). S přechodem na Windows 7 64bit a Java 1.7 64bit vyvstal jeden nepříjemný problém. Tím je generování výjimky Access violation v unitu JNI.pas v metodě TJNIEnv.ArgsToJValues, která má za úkol převést pole pascalských argumentů na pole argumentů pro Javu.

V originále zmíněná metoda vypadá takto:

function TJNIEnv.ArgsToJValues(const Args: array of const): PJValue;
var
  I: Integer;
begin
  if Length(Args) <> Length(FConvertedArgs) then
    SetLength(FConvertedArgs, Length(Args));
  for I := 0 to High(Args) do
    case Args[I].VType of
      vtInteger:
        FConvertedArgs[I].i := JInt(Args[I].VInteger);
      vtBoolean:
        FConvertedArgs[I].z := JBoolean(Args[I].VBoolean);
      vtWideChar:
        FConvertedArgs[I].c := JChar(Args[I].VWideChar);
      vtInt64:
        FConvertedArgs[I].j := JLong(Args[I].VInt64^);
      vtPointer, vtObject:
        FConvertedArgs[I].l := JObject(Args[I].VObject);
      vtAnsiString:
        FConvertedArgs[I].l := StringToJString(UTF8String(PAnsiString(Args[I].VAnsiString)^));
      vtWideString:
        FConvertedArgs[I].l := WideStringToJString(PWideString(Args[I].VWideString)^);
      {$IFDEF HAS_UNICODESTRING}
      vtUnicodeString:
        FConvertedArgs[I].l := WideStringToJString(PUnicodeString(Args[I].VUnicodeString)^);
      {$ENDIF}
      vtExtended:
        FConvertedArgs[I].d := Args[I].VExtended^; // Extended to Double (we lose Floats here)
    else
      raise EJNIError.Create('Unsupported variant argument');
    end;
  Result := PJValue(FConvertedArgs);
end;

Kompilátor si ovšem správně neporadí s použitými konstrukcemi pro převod řetězců na argumenty typu JValue, což má za následek nepříjemný pád, ke kterému dojde, když program zabrousí na některou z níže uvedených řádek kódu:

FConvertedArgs[I].l := StringToJString(UTF8String(PAnsiString(Args[I].VAnsiString)^));
FConvertedArgs[I].l := WideStringToJString(PWideString(Args[I].VWideString)^);
FConvertedArgs[I].l := WideStringToJString(PUnicodeString(Args[I].VUnicodeString)^);

Nepátral jsem sice po přesných příčinách těchto havárií, ale zdá se, že způsobené pády dostatečně řeší následující úprava kódu:

FConvertedArgs[I].l := StringToJString(UTF8String(PAnsiString(Args[I].VAnsiString)));
FConvertedArgs[I].l := WideStringToJString(PChar(PWideString(Args[I].VWideString)));
FConvertedArgs[I].l := WideStringToJString(PChar(PUnicodeString(Args[I].VUnicodeString)));

Tagy: , ,

Praxe

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS