请选择 进入手机版 | 继续访问电脑版

Lazarus中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

Lazarus IDE and 组件 下载地址版权申明
12
返回列表
楼主: tigerA15

【原创】Free Pascal (Lazarus)版Android NDK的应用示例之:常用数据类型的转换

[复制链接]

该用户从未签到

发表于 2015-2-14 00:58:24 | 显示全部楼层
请问有办法调用linux的底层驱动吗?
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-3-1 01:33:19 | 显示全部楼层
请问有办法调用linux的底层吗?
--------
同问,非常有必要。 网上JNI的demo几乎全部都是hello()  add(int,int)
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-7-27 16:28:27 | 显示全部楼层
雖然此帖已經過了一段時間了,不過因為最近有用到所以再次整理了一下JNI資料型態轉換的函式,大部分代碼都是受到樓主所啟發而擷取/延伸的,所以就不好意思另開主題囉!

這次的內容比較不一樣的是追加了以Double為例,二維不對齊動態陣列的轉換,其他的型態轉換都是仿製樓主的方法做的,貼出來只是想讓大家省點時間罷了,已經熟悉的朋友們看看就好吧~

(另,註解中二維陣列的行列是依台灣這邊的 "直行"、"橫列" 方式所定義,與大陸慣用的稱呼剛好對調,勿見怪!)

//------------------------------------------------------------------------------
Function JStringToString(Env:pJNIEnv;JavaStr:JString):String;Cdecl; //Java String轉Pascal String

var
pAnsiCharTMP:pAnsiChar;
IsCopy:JBoolean;
pIsCopy:pJBoolean;

begin
IsCopy:=JNI_TRUE;
pIsCopy:=@IsCopy;

if (JavaStr=Nil) then
begin
  Result:='';
  Exit;
end;

pAnsiCharTMP:= Env^^.GetStringUTFChars(Env,JavaStr,pIsCopy); //將輸入的Java String轉為pAnsiChar(相容C語言的零位元終止字元陣列指標),因後續有釋放資源的動作故不宜在外加掛一層StrPas()直接轉換成Pascal String。
if (pAnsiCharTMP=Nil) then
begin
  Result:='';
end
else
begin
  Result:=StrPas(pAnsiCharTMP); //將pAnsiChar轉為Pascal String後作為回傳值
  Env^^.ReleaseStringUTFChars(Env,JavaStr,pAnsiCharTMP); //輸入字串相關的轉換資源用完要釋放,否則會產生記憶體洩漏問題!
end;
end;
//------------------------------------------------------------------------------
Function StringToJString(Env:pJNIEnv;Str:String):JString;Cdecl; //Pascal String轉Java String副本範例
begin
Result:=Env^^.NewStringUTF(Env,@Str[1]); //依Pascal String內容建立新的Java String回傳
end;
//------------------------------------------------------------------------------
Function JStringArrayToStringDynArray(Env:pJNIEnv;JavaStrArray:JArray):TStringDynArray;Cdecl; //Java String陣列轉Pascal動態String陣列副本範例

var
I,ArraySize:JSize;
JObj:JObject;

begin
ArraySize:=Env^^.GetArrayLength(Env,JavaStrArray);
SetLength(Result,ArraySize);
for I := 0 to ArraySize-1 do
begin
  JObj:=Env^^.GetObjectArrayElement(Env,JavaStrArray,I);
  Result[I]:=JStringToString(Env, JString(JObj));
end;
end;
//------------------------------------------------------------------------------
Function StringDynArrayToJStringArray(Env:pJNIEnv;StringDynArray:TStringDynArray):JArray;Cdecl; //Pascal動態String陣列轉Java String陣列副本範例

var
I,ArraySize:Cardinal;

begin
ArraySize:=Length(StringDynArray);
//Java中String是Object,故要回傳String Array需建新的Object Array
Result:=Env^^.NewObjectArray(Env,ArraySize,Env^^.FindClass(Env,'java/lang/String'),StringToJString(Env,''));
for I := 0 to ArraySize-1 do
begin
  Env^^.SetObjectArrayElement(Env,Result,I,StringToJString(Env,StringDynArray[I]));
end;
end;
//------------------------------------------------------------------------------
Function JIntArrayToIntegerDynArray(Env:pJNIEnv;JavaIntArray:JIntArray):TIntegerDynArray;Cdecl; //Java Integer陣列轉Pascal動態Integer陣列副本範例

var
ArraySize:JInt;

begin
ArraySize:=Env^^.GetArrayLength(Env,JavaIntArray);
SetLength(Result,ArraySize);
Env^^.GetIntArrayRegion(Env,JavaIntArray,0,ArraySize,@Result[0]);
end;
//------------------------------------------------------------------------------
Function IntegerDynArrayToJIntArray(Env:pJNIEnv;IntArray:TIntegerDynArray):JIntArray;Cdecl; //Pascal動態Integer陣列轉Java Integer陣列副本範例

var
ArraySize:Cardinal;

begin
if (IntArray = nil) then
begin
  Result := nil;
  Exit;
end;
ArraySize:=High(IntArray)+1;
Result:=Env^^.NewIntArray(Env,ArraySize);
Env^^.SetIntArrayRegion(Env,Result,0,ArraySize,@IntArray[0]);
end;
//------------------------------------------------------------------------------
Function JDoubleArrayToDoubleDynArray(Env:pJNIEnv;JavaDblArray:JDoubleArray):TDoubleDynArray;Cdecl; //Java Double陣列轉Pascal動態Double陣列副本範例

var
ArraySize:JInt;

begin
ArraySize:=Env^^.GetArrayLength(Env,JavaDblArray);
SetLength(Result,ArraySize);
Env^^.GetDoubleArrayRegion(Env,JavaDblArray,0,ArraySize,@Result[0]);
end;
//------------------------------------------------------------------------------
Function DoubleDynArrayToJDoubleArray(Env:pJNIEnv;DblArray:TDoubleDynArray):JDoubleArray;Cdecl; //Pascal動態Double陣列轉Java Double陣列副本範例

var
ArraySize:Cardinal;

begin
if (DblArray = nil) then
begin
  Result := nil;
  Exit;
end;
ArraySize:=High(DblArray)+1;
Result:=Env^^.NewDoubleArray(Env,ArraySize);
Env^^.SetDoubleArrayRegion(Env,Result,0,ArraySize,@DblArray[0]);
end;
//------------------------------------------------------------------------------
Function JByteArrayToShortIntDynArray(Env:pJNIEnv;JavaByteArray:JByteArray):TShortIntDynArray;Cdecl; //Java Byte陣列轉Pascal動態ShortInt陣列副本範例

var
ArraySize:JInt;

begin
ArraySize:=Env^^.GetArrayLength(Env,JavaByteArray);
SetLength(Result,ArraySize);
Env^^.GetByteArrayRegion(Env,JavaByteArray,0,ArraySize,@Result[0]);
end;
//------------------------------------------------------------------------------
Function ShortIntDynArrayToJByteArray(Env:pJNIEnv;ShortIntArray:TShortIntDynArray):JByteArray;Cdecl; //Pascal動態ShortInt陣列轉Java Byte陣列副本範例

var
ArraySize:Cardinal;

begin
if (ShortIntArray = nil) then
begin
  Result := nil;
  Exit;
end;
ArraySize:=High(ShortIntArray)+1;
Result:=Env^^.NewByteArray(Env,ArraySize);
Env^^.SetByteArrayRegion(Env,Result,0,ArraySize,@ShortIntArray[0]);
end;
//------------------------------------------------------------------------------
Function JShortArrayToSmallIntDynArray(Env:pJNIEnv;JavaShortArray:JShortArray):TSmallIntDynArray;Cdecl; //Java Short陣列轉Pascal動態SmallInt陣列副本範例

var
ArraySize:JInt;

begin
ArraySize:=Env^^.GetArrayLength(Env,JavaShortArray);
SetLength(Result,ArraySize);
Env^^.GetShortArrayRegion(Env,JavaShortArray,0,ArraySize,@Result[0]);
end;
//------------------------------------------------------------------------------
Function SmallIntDynArrayToJShortArray(Env:pJNIEnv;SmallIntArray:TSmallIntDynArray):JShortArray;Cdecl; //Pascal動態SmallInt陣列轉Java Short陣列副本範例

var
ArraySize:Cardinal;

begin
if (SmallIntArray = nil) then
begin
  Result := nil;
  Exit;
end;
ArraySize:=High(SmallIntArray)+1;
Result:=Env^^.NewShortArray(Env,ArraySize);
Env^^.SetShortArrayRegion(Env,Result,0,ArraySize,@SmallIntArray[0]);
end;
//------------------------------------------------------------------------------
Function JDouble2DArrayToDoubleDyn2DArray(Env:pJNIEnv;JavaDbl2DArray:JArray):TDoubleDyn2DArray;Cdecl; //Java Double二維陣列轉Pascal動態Double二維陣列副本範例

var
I:Integer;
RowCount,ColumnCount:JInt;
JObj:JObject;

begin
Result:=Nil;
RowCount:=Env^^.GetArrayLength(Env,JavaDbl2DArray);
SetLength(Result,RowCount);

for I := 0 to RowCount-1 do
begin
  JObj:=Env^^.GetObjectArrayElement(Env,JavaDbl2DArray,I);
  ColumnCount:=Env^^.GetArrayLength(Env,JObj);
  SetLength(Result[I],ColumnCount); //為了避免傳入的Java陣列為非整齊矩陣,每列都個別設定其長度
  Env^^.GetDoubleArrayRegion(Env,JObj,0,ColumnCount,@Result[I,0]);
end;
end;
//------------------------------------------------------------------------------
Function DoubleDyn2DArrayToJDouble2DArray(Env:pJNIEnv;Dbl2DArray:TDoubleDyn2DArray):JArray;Cdecl; //Pascal動態Double二維陣列轉Java Double二維陣列副本範例

var
I,RowCount:Cardinal;
TMPDoubleArray:TDoubleDynArray;
TMPJDoubleArray:JDoubleArray;

begin
if (Dbl2DArray = nil) then
begin
  Result := nil;
  Exit;
end;
RowCount:=High(Dbl2DArray)+1;
Result:=Env^^.NewObjectArray(Env,RowCount,Env^^.FindClass(Env,'[D'),nil);
for I := 0 to (RowCount-1) do
begin
  TMPDoubleArray:=Nil;
  SetLength(TMPDoubleArray,High(Dbl2DArray[I])+1); //矩陣每列的元素數可能不定
  move(Dbl2DArray[I,0],TMPDoubleArray[0],(High(Dbl2DArray[I])+1)*SizeOf(Double));
  TMPJDoubleArray:=DoubleDynArrayToJDoubleArray(Env,TMPDoubleArray);
  Env^^.SetObjectArrayElement(Env,Result,I,TMPJDoubleArray);
end;
end;
//------------------------------------------------------------------------------
回复 支持 反对

使用道具 举报

该用户从未签到

 楼主 发表于 2016-3-1 15:39:37 | 显示全部楼层
chenyuchih 发表于 2015-7-27 16:28
雖然此帖已經過了一段時間了,不過因為最近有用到所以再次整理了一下JNI資料型態轉換的函式,大部分代碼都是 ...

居然遇到大神,,,請教一下,用freepascal寫的.so,用在android里面,若multithread并發執行之,很快就出現libc的錯誤(message太抽象沒多少幫助),在native api里面用TCriticalSection鎖定單一執行都不行,非要在android層面用synchronized來執行此api,極其郁悶,是否有解決辦法??
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2016-3-2 15:31:55 | 显示全部楼层
兄台言重了,別這麼稱呼我,小弟只是業餘的寫手,很多東西也還在學習中...

對於MultiThread的部分我沒什麼經驗,希望有其他的高手能在您的另一篇指點一二,也讓我琢磨琢磨~
回复 支持 反对

使用道具 举报

QQ|手机版|小黑屋|Lazarus中国|Lazarus中文社区 ( 鄂ICP备16006501号-1

GMT+8, 2020-7-12 13:35 , Processed in 0.048870 second(s), 21 queries .

Powered by Discuz! F1.0 Build 20160930

© 2001-2020 Comsenz Inc. & Discuz! Fans

快速回复 返回顶部 返回列表