Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Delphi使用来自Android Jni包装器的过程_Java_Android_Delphi_Firemonkey Fm3 - Fatal编程技术网

Java Delphi使用来自Android Jni包装器的过程

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

您好,我已经用C创建了一个Android类,它执行一些操作。 在这些程序中,我想使用以下程序:(仅用于使用Delphi进行测试)

当然,我的testlib.so是构建和编译的(使用cygwin构建NDK),并与我的Delphi项目一起部署

在我的Delphi Firemonkey客户端中,我以如下方式使用此过程:

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声明匹配,但它在三个方面不匹配:

  • 正如Remy指出的,您使用的是封装Java类
    Java.lang.JObject
    ,而不是类型
    JNIObject
    (来自RTL单元Androidapi.JNI.pas),而不是类型
    JNIObject
    (来自RTL单元Androidapi.JNI.pas),后者相当于JNI类型
    JObject
    。然而,这主要是不相关的,因为
  • 您的底层C方法使用
    jclass
    参数来暗示它是静态/类方法,但是您的Delphi导入声明试图使用
    jobject
    等效项,从而导致不匹配。它应该声明类型为
    JNIClass
    的参数
  • 底层C方法使用
    jbytearray
    JNI参数类型,但Delphi声明使用类型
    指针
    。相反,您应该使用Delphi等效于
    jbytearray
    ,即
    JNIByteArray
  • 只有当双方的所有参数和调用约定直接匹配时,调用才会成功

    稍微相关的一点是,告知读者.so库是如何在Delphi项目中部署的,以及您在运行时使用了什么路径表达式来访问它,这可能是有益的,因为这还远远不清楚


    为了执行类似的实验,我有一个.so文件,我将部署管理器设置为部署到assets\internal\Deployment文件夹。这意味着我可以使用
    TPath.Combine(TPath.GetDocumentsPath,LibName)
    从Android应用程序代码中引用库文件。

    您的Delphi声明需要与基础C声明匹配,但它在三个方面不匹配:

  • 正如Remy指出的,您使用的是封装Java类
    Java.lang.JObject
    ,而不是类型
    JNIObject
    (来自RTL单元Androidapi.JNI.pas),而不是类型
    JNIObject
    (来自RTL单元Androidapi.JNI.pas),后者相当于JNI类型
    JObject
    。然而,这主要是不相关的,因为
  • 您的底层C方法使用
    jclass
    参数来暗示它是静态/类方法,但是您的Delphi导入声明试图使用
    jobject
    等效项,从而导致不匹配。它应该声明类型为
    JNIClass
    的参数
  • 底层C方法使用
    jbytearray
    JNI参数类型,但Delphi声明使用类型
    指针
    。相反,您应该使用Delphi等效于
    jbytearray
    ,即
    JNIByteArray
  • 只有当双方的所有参数和调用约定直接匹配时,调用才会成功

    稍微相关的一点是,告知读者.so库是如何在Delphi项目中部署的,以及您在运行时使用了什么路径表达式来访问它,这可能是有益的,因为这还远远不清楚


    为了执行类似的实验,我有一个.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);