java - 使用 JNI 仅将缓冲区的一部分从 native 代码复制到 Java

标签 java c java-native-interface byte arrays

我在 C 中有一个非常大的 char 缓冲区,需要将它的一部分复制到 Java 数组中。

具体来说,我需要从 16,384 开始到 32000 结束的元素。我该怎么做?

最初我试过这个:

jbyte * bytes = (* env) -> GetByteArrayElements (env, array, NULL); 
memmove (bytes, (jbyte *) buffer, buffer_size);
(* Env) -> ReleaseByteArrayElements (env, array, (jbyte *) bytes, 0); 
(* Env) -> CallStaticVoidMethod (env, cls, mid, buffer_size); 

但是使用这段代码传输整个缓冲区,而且它非常大(超过 40 MB)。我只需要一小部分缓冲区。

编辑: 非常感谢,但是你的版本不太好用。我按如下方式应用它: memmove (array, (jbyte *) (buffer + numbers), 16385); 在缓冲区中 - 在每次迭代时将新的 16384 字节复制到“缓冲区”。 此类数字中缓冲区的数量和数量分别为: 16384 - 0

32,768 - 16,385

49152 - 32769

65536 - 49153

81,920 - 65,537

98,304 - 81,921

即在右侧列的“数字”中轮流进行每次迭代。 结果,复制的字节并不总是成功的。第一次迭代总是成功的。此外,成功与失败交替出现。 memtcpy 给出相同的结果。会有什么建议?如何解决问题?

编辑2: 我的代码:

JNIEXPORT jint work (JNIEnv * env, jobject obj, jbyteArray array) 
{ 
int argc; 
char * args [3]; 
char * argv [3]; 
argv [1] = "Music/Tg.mp3"; 
argv [2] = "testwavS3.flac"; 
argc = 3; 
sox_effects_chain_t * chain; 
sox_effect_t * e; 
static sox_format_t * in, * out; / * input and output files * / 

         char * buffer; 
         size_t buffer_size; 

         size_t number_read; 



/ * All libSoX applications must start by initialising the SoX library * / 
sox_init (); 

/ * Open the input file (with default parameters) * / 
in = sox_open_read (argv [1], NULL, NULL, NULL); 
# Define MAX_SAMPLES (size_t) 8192 
__android_log_write (ANDROID_LOG_ERROR, "Read", "Haha"); 
sox_sample_t samples [MAX_SAMPLES]; / * Temporary store whilst copying. * / 


jclass cls; 
jmethodID mid, mid2; 
cls = (* env) -> GetObjectClass (env, obj); 
mid = (* env) -> GetStaticMethodID (env, cls, "testt", 
"(I) V"); 

jbyteArray bytearrayBuffer = (* env) -> NewByteArray (env, & in-> signal.length); / / construct a new byte array 
out = sox_open_memstream_write (& buffer, & buffer_size, & in-> signal, NULL, "sox", NULL); 
int numbers = 0; 

in-> encoding.bits_per_sample = 16; 
out-> encoding.bits_per_sample = 16; 
(* Env) -> GetByteArrayElements (env, array, NULL); 
while (number_read = sox_read (in, samples, MAX_SAMPLES)) { 

sox_write (out, samples, number_read); 

memmove (array, (jbyte *) (buffer + numbers), (buffer_size-numbers)); 


numbers + = buffer_size-numbers; 

(* Env) -> CallStaticVoidMethod (env, cls, mid, buffer_size); 



} 

          sox_close (out); 

          sox_close (in); 

        # If! Defined FIXED_BUFFER 
          free (buffer); 
        # Endif 




} 

在 Java 中使用 SoX 解码音频并提供缓冲区。

最佳答案

如果您只需要 Java 数组的一部分,请查看 JNI 方法 Get<PrimitiveType>ArrayRegionRelease<PrimitiveType>ArrayRegion .

如果您只需要C++ 数组的一部分,您可以在memmove 中传递不同的起始地址和长度。 .

关于java - 使用 JNI 仅将缓冲区的一部分从 native 代码复制到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6282776/

相关文章:

java - 如何不为返​​回类型为 int 的方法返回任何内容

java - 以编程方式编辑 java 源文件

java - 点击主页按钮然后单击应用程序图标返回到同一 Activity 后应用程序崩溃

c - C语言对8位数字的算术运算过程

c - Pragma 及其在我的代码中的合适用途?

c - 在没有 malloc、brk 或 mmap 的情况下,BareMetalOS 如何在 Assembly 中分配内存?

java - 使用JNI调用给定DLL文件中定义的函数

java - 如何从 NDK C++ 调用 Java?

android - Android Studio : "process ... command finished with non-zero exit value 2" 上的 NDK 问题

java - Linux 上的 Oracle Service Bus maven 构建时间比 Windows 慢 30 倍