728x90
지난번 Lazarus(free pascal)로 생성한 so파일을 안드로이드에 연동하는법을 배워보았습니다
그 예제에서는 int값만 주고 받았는데 이게 주고받는게 단순하지 않은 타입들이 있습니다
그 문제는 흔히 사용하는 string에서부터 시작됩니다
우선 java의 String은 유니코드로 저장되는 char 배열이기에 lazarus String으로 쓰기위해선 UTF- 8로 인코딩을 해줘야한다
java에서 넘어온 string값 변환(JNI -> Lazarus)
var
jsTemp : JString;
sTemp : String;
begin
sTemp := JStringTostring(jsTemp);
end;
function JStringToString(AJString: jstring): string;
var
Env: PJNIEnv;
pChar: PChar;
begin
(GlobalJavaVM^^).GetEnv(GlobalJavaVM, @Env, JNI_VERSION_1_2);
pChar := (Env^^).GetStringUTFChars(Env, AJString, nil);
Result := String(pChar);
(Env^^).ReleaseStringUTFChars(Env, AJString, pChar);
end;
반대로 lazarus에서 JString으로 java로 넘겨줘야 할 경우 (Lazarus -> JNI)
function passToJava((PEnv: PJNIEnv; cls: JClass): JString; cdecl;
var
sTemp : String;
begin
sTemp := 'hello world';
Result := StringToJString(sTemp);
end;
function StringToJString(AString: string): jstring;
var
Env: PJNIEnv;
begin
(GlobalJavaVM^^).GetEnv(GlobalJavaVM, @Env, JNI_VERSION_USE);
Result := (Env^^).NewStringUTF(Env, PChar(AString));
end;
변환용 함수는 그대로 긁어가서 호출해서 사용하면 된다
다음으로 String array는 어떻게 넘겨야 할 것인가
전달 할 Java측 소스
//선언
@Keep
public static native int PassArr(String[] arVal);
//호출
PassArr(String[] arVal);
수신받을 Lazarus측 소스
function PassArr(PEnv: PJNIEnv; cls: JClass; arVal: jobjectArray):JInt; cdecl;
var
asTemp : Array of String;
i,nCnt : Integer;
jsTemp : Jstring;
sTemp : string;
begin
nCnt := (PEnv^).GetArrayLength(PEnv, arVal);
SetLength(asTemp, nCnt);
for i := 0 to nCnt-1 do
begin
jsTemp := (PEnv^).GetObjectArrayElement(PEnv, arVal, i); //jstring으로 추출
sTemp := JStringToString(jsTemp); //native에서 쓸 수 있게 string 변환
asTemp[i] := sTemp; //이건 쓰기나름..
end;
end
위와같이 jobjectArray 형식으로 수신하여 길이를 구해서 jstring값을 하나씩 가져온다
※ 참고사이트 : wiki.lazarus.freepascal.org/Android_Programming#Android_JNI
틀린내용이나 질문은 댓글로 남겨주세요
728x90