android JNI JString to String

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

android JNI JString to String

herux
I have a strange problem, I pass data from the android String via JNI. pass data from FreePascal wideString successfully using the following code

NewString: function (Env: PJNIEnv; const Unicode: PJChar; Len: JSize): JString; cdecl;
GetStringChars:function(Env:PJNIEnv;Str:JString;IsCopy:PJBoolean):PJChar; cdecl;

function JNI_WideStringToJString(Env: PJNIEnv; const WStr: WideString): JString;
begin
  Result := Env^.NewString(Env, Pointer(WStr), Length(WStr));
end;

but when passing data JString to widestring, using this code :

function JNI_JStringToWideString(Env: PJNIEnv; JStr: JString): WideString;
var
  IsCopy: JBoolean;
  Chars: PJChar;
begin
  if (JStr = nil) then begin
    Result := '';
    Exit;
  end;

  Chars := Env^.GetStringChars(Env, JStr, IsCopy);
  if (Chars = nil) then begin
    Result := ''
  end else begin
    Result := WideString(Chars);
    Env^.ReleaseStringChars(Env, JStr, Chars);
  end;
end;

return only 1 character leading.
if anyone has ever experienced ? or there's something wrong with JNI header ?

thanks
-
Reply | Threaded
Open this post in threaded view
|

RE : [fpc-pascal] android JNI JString to String

Ludo Brands
PJChar is defined as a pointer to a word. Casting to WideString isn't
working since internally Widestring has extra bytes for reference count and
string length. These extra bytes are locate before the actual string. This
explains why assigning Pointer(WStr) to PJChar works.
Try
 Result := WideString(PWideChar(Chars));  
PWideChar matches probably PJChar and the compiler knows how to convert
PWideChar to WideString.

Ludo



-----Message d'origine-----
De : [hidden email]
[mailto:[hidden email]] De la part de herux
Envoyé : mardi 26 avril 2011 10:37
À : [hidden email]
Objet : [fpc-pascal] android JNI JString to String


I have a strange problem, I pass data from the android String via JNI. pass
data from FreePascal wideString successfully using the following code

NewString: function (Env: PJNIEnv; const Unicode: PJChar; Len: JSize):
JString; cdecl;
GetStringChars:function(Env:PJNIEnv;Str:JString;IsCopy:PJBoolean):PJChar;
cdecl;

function JNI_WideStringToJString(Env: PJNIEnv; const WStr: WideString):
JString; begin
  Result := Env^.NewString(Env, Pointer(WStr), Length(WStr)); end;

but when passing data JString to widestring, using this code :

function JNI_JStringToWideString(Env: PJNIEnv; JStr: JString): WideString;
var
  IsCopy: JBoolean;
  Chars: PJChar;
begin
  if (JStr = nil) then begin
    Result := '';
    Exit;
  end;

  Chars := Env^.GetStringChars(Env, JStr, IsCopy);
  if (Chars = nil) then begin
    Result := ''
  end else begin
    Result := WideString(Chars);
    Env^.ReleaseStringChars(Env, JStr, Chars);
  end;
end;

return only 1 character leading.
if anyone has ever experienced ? or there's something wrong with JNI header
?

thanks


-----
-
--
View this message in context:
http://free-pascal-general.1045716.n5.nabble.com/android-JNI-JString-to-Stri
ng-tp4340388p4340388.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] android JNI JString to String

herux
thanks for the response.

I am doing what you suggest. but it's still the same.

I debug this line of code using android log

Chars := Env^.GetStringChars(Env, AJString, nil);
__android_log_write(ANDROID_LOG_DEBUG,'proj_debug',PChar(Chars));

and the log I retrieved :

04-26 17:53:17.942: DEBUG/proj_debug(711): e <--- only "e" character

from input AJString = eNp9zt0KwjAMBeBXCecBrApeCEmG+iRzdrX+dKMrMn16Y0G8M5Cr75ATbub7jR4+T3FIgtViiUa5VS5xGPsfrA2c8lG5o5NghrJX7ikInqCzYCo5pgCKgq3NJ1x1+KuvqjEVH3yuXGuc3b4oX2knAO2tfgM6fNHEdbb2jGv1DUfmNOA=

so I thought, this is not about that. but I do not know why

-
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] android JNI JString to String

Jonas Maebe-2

On 26 Apr 2011, at 13:06, herux wrote:

> I debug this line of code using android log
>
> Chars := Env^.GetStringChars(Env, AJString, nil);
> __android_log_write(ANDROID_LOG_DEBUG,'proj_debug',PChar(Chars));
>
> and the log I retrieved :
>
> 04-26 17:53:17.942: DEBUG/proj_debug(711): e <--- only "e" character

That is normal, because Chars is probably an array of jchar, and a  
jchar is utf-16 (= widechar). That means that if you treat it as pchar  
and it only contains plain ASCII, the second "ansichar" will always be  
#0 on a little endian system (on a big endian system, the first  
"ansichar" will already be #0).


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

RE : RE : [fpc-pascal] android JNI JString to String

Ludo Brands
In reply to this post by herux
Pchar(Chars) interpretes your widechars as chars. The widechar e is
converted to the chars e and #0. The #0 is end of line for a pchar. So your
debug output is as expected.

Take a look at
http://groups.google.com/group/android-ndk/browse_thread/thread/e0ab7aefb398
2c45. It talks about the same problem calling GetStringChars from C. The
function returns non null terminated utf16 data.

You could also go the hard way, something along the lines of:
  Chars := Env^.GetStringChars(Env, JStr, @IsCopy);
  if (Chars = nil) then begin
    Result := ''
  end else begin
    len:=Env^.GetStringLength(Env, JStr);
    setlength(Result,len);
    move(Chars,Result[1],len*2);
    Env^.ReleaseStringChars(Env, JStr, Chars);
  end;



-----Message d'origine-----
De : [hidden email]
[mailto:[hidden email]] De la part de herux
Envoyé : mardi 26 avril 2011 13:06
À : [hidden email]
Objet : Re: RE : [fpc-pascal] android JNI JString to String


thanks for the response.

I am doing what you suggest. but it's still the same.

I debug this line of code using android log

Chars := Env^.GetStringChars(Env, AJString, nil);
__android_log_write(ANDROID_LOG_DEBUG,'proj_debug',PChar(Chars));

and the log I retrieved :

04-26 17:53:17.942: DEBUG/proj_debug(711): e <--- only "e" character

from input AJString =
eNp9zt0KwjAMBeBXCecBrApeCEmG+iRzdrX+dKMrMn16Y0G8M5Cr75ATbub7jR4+T3FIgtViiUa5
VS5xGPsfrA2c8lG5o5NghrJX7ikInqCzYCo5pgCKgq3NJ1x1+KuvqjEVH3yuXGuc3b4oX2knAO2t
fgM6fNHEdbb2jGv1DUfmNOA=

so I thought, this is not about that. but I do not know why



-----
-
--
View this message in context:
http://free-pascal-general.1045716.n5.nabble.com/android-JNI-JString-to-Stri
ng-tp4340388p4340649.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] android JNI JString to String

herux
Yes, there's bug. thanks you.
I using GetStringUTFChars

function JNI_JStringToString(Env: PJNIEnv; JStr: jstring): String;
var
  IsCopy: Pjboolean;
  Chars: PChar;
begin
  if JStr = nil then
  begin
    Result := '';
    Exit;
  end;

  Chars:= Env^.GetStringUTFChars(Env, JStr, IsCopy);
  if Chars = nil then
     Result := ''
  else
    Begin
      Result := String(Chars);
      Env^.ReleaseStringUTFChars(Env, JStr, Chars);
    end;
end;
-