Java Delphi使用来自Android Jni包装器的过程
您好,我已经用C创建了一个Android类,它执行一些操作。 在这些程序中,我想使用以下程序:(仅用于使用Delphi进行测试) 当然,我的testlib.so是构建和编译的(使用cygwin构建NDK),并与我的Delphi项目一起部署 在我的Delphi Firemonkey客户端中,我以如下方式使用此过程:Java Delphi使用来自Android Jni包装器的过程,java,android,delphi,firemonkey-fm3,Java,Android,Delphi,Firemonkey Fm3,您好,我已经用C创建了一个Android类,它执行一些操作。 在这些程序中,我想使用以下程序:(仅用于使用Delphi进行测试) 当然,我的testlib.so是构建和编译的(使用cygwin构建NDK),并与我的Delphi项目一起部署 在我的Delphi Firemonkey客户端中,我以如下方式使用此过程: Java_Test_Project_Decode:procedure(PEnv: PJNIEnv; Obj:JObject;dataIn:Pointer;DataOut:Pointer
Java_Test_Project_Decode:procedure(PEnv: PJNIEnv; Obj:JObject;dataIn:Pointer;DataOut:Pointer); cdecl;
当然,在我加载我的库之后:
Procedure LoadMyLib();
begin
FMyLib := LoadLibrary(PChar(LibFolder + LibTest));
if FMyLib = 0 then
begin
Exit;
end
else
begin
Java_Test_Project_Decode:=GetProcAddress(FMyLib,'Java_Test_Project_Decode');
if not assigned (Java_Test_Project_Decode) then
begin
Exit; // Java_Test_Project_Decode procedure not loaded
end else
begin
// OK Java_Test_Project_Decode procedure loaded
end;
end;
end;
然后我使用以下程序:
Procedure TestMyProcedure (ADataIn: pointer; ASize: integer);
var
ADataOut:Pointer;
begin
// ADataIn pointer is not empty
Java_Test_Project_Decode(PEnv,Obj,ADataIn,ADataOut);
end;
但在这里我遇到了一个例外,应用程序崩溃了
有人能帮我修一下吗
谢谢
更新:
我可以按如下方式消除ADataOut
:
JNIEXPORT void Java_Test_Project_Decode(JNIEnv* env, jclass clazz,jbyteArray dataIn)
{
jsize len = (*env)->GetArrayLength(env, dataIn);
LOGV("JNI call Decode test dataIn Size = %d",len);
jbyte *pByteIn = (*env)->GetByteArrayElements(env, dataIn, 0);
// some routines
(*env)->ReleaseByteArrayElements(env, dataIn, pByteIn, 0);
}
我的德尔福宣言:
Java_Test_Project_Decode:procedure(PEnv: PJNIEnv; Obj:JObject;dataIn:Pointer); cdecl;
Procedure TestMyProcedure (ADataIn: pointer; ASize: integer);
begin
// ADataIn pointer is not empty
Java_Test_Project_Decode(PEnv,Obj,ADataIn);
end;
但总是有同样的异常和错误,我甚至试图得到
jsize len = (*env)->GetArrayLength(env, dataIn);
LOGV("JNI call Decode test dataIn Size = %d",len);
相同的错误。您的Delphi声明需要与基础C声明匹配,但它在三个方面不匹配:
Java.lang.JObject
,而不是类型JNIObject
(来自RTL单元Androidapi.JNI.pas),而不是类型JNIObject
(来自RTL单元Androidapi.JNI.pas),后者相当于JNI类型JObject
。然而,这主要是不相关的,因为jclass
参数来暗示它是静态/类方法,但是您的Delphi导入声明试图使用jobject
等效项,从而导致不匹配。它应该声明类型为JNIClass
的参数jbytearray
JNI参数类型,但Delphi声明使用类型指针
。相反,您应该使用Delphi等效于jbytearray
,即JNIByteArray
为了执行类似的实验,我有一个.so文件,我将部署管理器设置为部署到assets\internal\Deployment文件夹。这意味着我可以使用
TPath.Combine(TPath.GetDocumentsPath,LibName)
从Android应用程序代码中引用库文件。您的Delphi声明需要与基础C声明匹配,但它在三个方面不匹配:
Java.lang.JObject
,而不是类型JNIObject
(来自RTL单元Androidapi.JNI.pas),而不是类型JNIObject
(来自RTL单元Androidapi.JNI.pas),后者相当于JNI类型JObject
。然而,这主要是不相关的,因为jclass
参数来暗示它是静态/类方法,但是您的Delphi导入声明试图使用jobject
等效项,从而导致不匹配。它应该声明类型为JNIClass
的参数jbytearray
JNI参数类型,但Delphi声明使用类型指针
。相反,您应该使用Delphi等效于jbytearray
,即JNIByteArray
为了执行类似的实验,我有一个.so文件,我将部署管理器设置为部署到assets\internal\Deployment文件夹。这意味着我可以使用
TPath.Combine(TPath.GetDocumentsPath,LibName)
引用Android应用程序代码中的库文件。TestMyProcedure()
中的ADataOut
未初始化,但Java\u Test\u Project\u Decode()
正在尝试访问和写入它Java\u Test\u Project\u Decode()
需要ADataIn
和ADataOut
作为指向至少2个元素大小的有效Java字节数组的指针。@RemyLebeau,我可以在Delphi和Java过程中消除ADateOut
,但仍然会得到相同的异常和错误。虽然ADataIn
不是空的,请编辑您的问题以显示更新的代码。@RemyLebeau我更新代码只是为了获取数据大小并记录它,但在Android上总是有相同的错误和例外,Delphi有一个JObject
接口,它与JNI的JObject
类型分开。确保在函数声明中使用JNI类型。TestMyProcedure()
中的ADataOut
未初始化,但Java\u Test\u Project\u Decode()
正在尝试访问和写入它Java\u Test\u Project\u Decode()
需要ADataIn
和ADataOut
作为指向至少2个元素大小的有效Java字节数组的指针。@RemyLebeau,我可以在Delphi和Java过程中消除ADateOut
,但仍然会得到相同的异常和错误。虽然ADataIn
不是空的,请编辑您的问题以显示更新的代码。@RemyLebeau我更新代码只是为了获取数据大小并记录它,但在Android上总是有相同的错误和例外,Delphi有一个JObject
接口,它与JNI的JObject
类型分开。确保您在y中使用的是JNI类型
jsize len = (*env)->GetArrayLength(env, dataIn);
LOGV("JNI call Decode test dataIn Size = %d",len);