Java 调用返回类型为非原语的方法时使用JNI调用NDK

Java 调用返回类型为非原语的方法时使用JNI调用NDK,java,android,c++,c,android-ndk,Java,Android,C++,C,Android Ndk,我需要c结构和java类模型之间的映射。原因是我想调用一个c方法,该方法返回一个我在java中有模型类的结构。我已经成功地用原始数据类型调用了本机方法,或者从Java代码中调用了void。但我的案例中没有任何对象AlacFile或只是对象obj。 请参阅代码以了解我所说的内容 c代码 alac_file * Java_org_phlo_AirReceiver_AirReceiver_create_alac2(JNIEnv* env, jclass thiz, int samplesi

我需要c结构和java类模型之间的映射。原因是我想调用一个c方法,该方法返回一个我在java中有模型类的结构。我已经成功地用原始数据类型调用了本机方法,或者从Java代码中调用了void。但我的案例中没有任何对象AlacFile或只是对象obj。 请参阅代码以了解我所说的内容

c代码

alac_file * Java_org_phlo_AirReceiver_AirReceiver_create_alac2(JNIEnv* env,
      jclass thiz, int samplesize, int numchannels) {

return create_alac(samplesize, numchannels);
}

alac_file *create_alac(int samplesize, int numchannels){
   alac_file *newfile = (alac_file*)malloc(sizeof(alac_file));

   newfile->samplesize = samplesize;
   newfile->numchannels = numchannels;
   newfile->bytespersample = (samplesize / 8) * numchannels;

   return newfile;
}
我在c类中定义了alac_文件的结构

我从java调用这个方法,如下所示

public native AlacFile create_alac2(int samplesize , int numchannels );
    01-28 03:51:56.202: I/AirReceiver(31668): Registered AirTunes service           '08606EB2F10B@localhost (p2p0)' on fe80::860:6eff:feb2:f10b%p2p0/fe80::860:6eff:feb2:f10b%p2p0%5
01-28 03:51:56.212: I/System.out(31668): Loading libraray BEFORE 1111
01-28 03:51:56.212: D/dalvikvm(31668): Trying to load lib /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0
01-28 03:51:56.232: D/dalvikvm(31668): Added shared lib /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0
01-28 03:51:56.232: D/dalvikvm(31668): No JNI_OnLoad found in /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0, skipping init
01-28 03:51:56.232: I/System.out(31668): Loading libraray AFTER 1111
01-28 03:51:56.232: W/dalvikvm(31668): No implementation found for native Lorg/phlo/AirReceiver/AirReceiver;.create_alac2:(II)Lcom/beatofthedrum/alacdecoder/AlacFile;
01-28 03:51:56.242: W/dalvikvm(31668): threadid=11: thread exiting with uncaught exception (group=0x419d6700)
01-28 03:51:56.252: E/AndroidRuntime(31668): FATAL EXCEPTION: AsyncTask #1
01-28 03:51:56.252: E/AndroidRuntime(31668): java.lang.RuntimeException: An error occured while executing doInBackground()
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.run(FutureTask.java:239)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.lang.Thread.run(Thread.java:841)
01-28 03:51:56.252: E/AndroidRuntime(31668): Caused by: java.lang.UnsatisfiedLinkError: Native method not found: org.phlo.AirReceiver.AirReceiver.create_alac2:(II)Lcom/beatofthedrum/alacdecoder/AlacFile;
01-28 03:51:56.252: E/AndroidRuntime(31668):  at org.phlo.AirReceiver.AirReceiver.create_alac2(Native Method)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at org.phlo.AirReceiver.AirReceiver.main(AirReceiver.java:461)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at com.example.droidairplayandroid.MainActivity$AirServerAsyncTask.doInBackground(MainActivity.java:66)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at com.example.droidairplayandroid.MainActivity$AirServerAsyncTask.doInBackground(MainActivity.java:1)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-28 03:51:56.252: E/AndroidRuntime(31668):  ... 4 more
01-28 03:51:56.282: I/Process(31668): Sending signal. PID: 31668 SIG: 9
产出

已成功编译并运行

调用上述本机方法时收到崩溃。具体情况如下

public native AlacFile create_alac2(int samplesize , int numchannels );
    01-28 03:51:56.202: I/AirReceiver(31668): Registered AirTunes service           '08606EB2F10B@localhost (p2p0)' on fe80::860:6eff:feb2:f10b%p2p0/fe80::860:6eff:feb2:f10b%p2p0%5
01-28 03:51:56.212: I/System.out(31668): Loading libraray BEFORE 1111
01-28 03:51:56.212: D/dalvikvm(31668): Trying to load lib /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0
01-28 03:51:56.232: D/dalvikvm(31668): Added shared lib /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0
01-28 03:51:56.232: D/dalvikvm(31668): No JNI_OnLoad found in /data/app-lib/com.example.airreceiver-1/libhairtunes.so 0x4212dad0, skipping init
01-28 03:51:56.232: I/System.out(31668): Loading libraray AFTER 1111
01-28 03:51:56.232: W/dalvikvm(31668): No implementation found for native Lorg/phlo/AirReceiver/AirReceiver;.create_alac2:(II)Lcom/beatofthedrum/alacdecoder/AlacFile;
01-28 03:51:56.242: W/dalvikvm(31668): threadid=11: thread exiting with uncaught exception (group=0x419d6700)
01-28 03:51:56.252: E/AndroidRuntime(31668): FATAL EXCEPTION: AsyncTask #1
01-28 03:51:56.252: E/AndroidRuntime(31668): java.lang.RuntimeException: An error occured while executing doInBackground()
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.run(FutureTask.java:239)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.lang.Thread.run(Thread.java:841)
01-28 03:51:56.252: E/AndroidRuntime(31668): Caused by: java.lang.UnsatisfiedLinkError: Native method not found: org.phlo.AirReceiver.AirReceiver.create_alac2:(II)Lcom/beatofthedrum/alacdecoder/AlacFile;
01-28 03:51:56.252: E/AndroidRuntime(31668):  at org.phlo.AirReceiver.AirReceiver.create_alac2(Native Method)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at org.phlo.AirReceiver.AirReceiver.main(AirReceiver.java:461)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at com.example.droidairplayandroid.MainActivity$AirServerAsyncTask.doInBackground(MainActivity.java:66)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at com.example.droidairplayandroid.MainActivity$AirServerAsyncTask.doInBackground(MainActivity.java:1)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-28 03:51:56.252: E/AndroidRuntime(31668):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-28 03:51:56.252: E/AndroidRuntime(31668):  ... 4 more
01-28 03:51:56.282: I/Process(31668): Sending signal. PID: 31668 SIG: 9

必须定义函数才能返回jobject。用于在C中创建Java对象的新实例,填充它,然后返回Java。

可能是您的方法签名有问题

public native AlacFile create_alac2(int samplesize , int numchannels );
试试看

public native AlacFile createAlac2(int samplesize , int numchannels );//remove '-' here

可能是它的拆分创建和alac2

您可能需要将Java中的C结构解析为直接字节(或任何形式)缓冲区,或者使用所谓的“反向”JNI从C调用来创建和操作Java对象的元素。@ChrisStratton,因为我发现本地方法找不到crash。我将尝试反向JNI调用。但是,您能否也指导我您所说的将Java中的C结构解析为直接字节(或其他)的方法缓冲区as无法正确获取。请阅读ByteBuffer上的文档。您的崩溃可能是一些无关紧要的问题,与此功能挑战无关,例如命名问题,甚至构建问题。我也尝试过jobject。但随后被错误捕获为Ljava.lang.Object。您可能做错了什么。尝试按照我链接的示例。帮助我调用其他类似函数。