我在 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>ArrayRegion
和 Release<PrimitiveType>ArrayRegion
.
如果您只需要C++ 数组的一部分,您可以在memmove
中传递不同的起始地址和长度。 .
关于java - 使用 JNI 仅将缓冲区的一部分从 native 代码复制到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6282776/