使用 JNI 将 OutputStream 写入 C 缓冲区
Having an OutputStream write in a C buffer using JNI
我正在尝试在我的 C 程序中处理 DNG 文件(我从 DngCreator 获得)。
我不想将它保存到 Java 中的磁盘,然后从 C 加载它,因为这会浪费时间并耗尽闪存(我每个会话需要大约 40 个 DNG,所以超过 800 MB)。
我对 Java 不是很熟悉,但是有没有办法覆盖 OutputStream 并添加我自己的 JNI 调用?
假设您有一个可以与 OutputStream 一起使用的 DNG 创建函数,您可以实例化一个 ByteArrayOutputStream,将其作为参数传递给您的 DNG 创建函数,然后通过方法调用获取字节数组 toByteArray()
.
然后可以将其传递给本机 C 库。
在代码中这可能是这样的:
package com.software7.jni;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Main {
private native void transferDng(byte[] data);
private void someDNGCreationFunction(OutputStream outputStream)
throws IOException {
outputStream.write("hello world!".getBytes(UTF_8));
}
private void test() throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
someDNGCreationFunction(baos);
transferDng(baos.toByteArray());
}
}
public static void main(String[] args) {
System.loadLibrary("Native");
Main m = new Main();
try {
m.test();
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后本机端可以从字节数组中检索数据,例如看到这个很好的答案 。
#include <string.h>
#include <stdlib.h>
#include <jni.h>
#include "com_software7_jni_Main.h"
JNIEXPORT void JNICALL Java_com_software7_jni_Main_transferDng
(JNIEnv *env, jobject obj, jbyteArray dng) {
jsize num_bytes = (*env)->GetArrayLength(env, dng);
jbyte *b = (*env)->GetByteArrayElements(env, dng, 0);
char *buffer = malloc(num_bytes);
memcpy(buffer, b, num_bytes);
(*env)->ReleaseByteArrayElements(env, dng, b, 0);
//do something with the buffer, here a printf only for testing
printf("%.*s", num_bytes, buffer);
free(buffer);
return;
}
我正在尝试在我的 C 程序中处理 DNG 文件(我从 DngCreator 获得)。 我不想将它保存到 Java 中的磁盘,然后从 C 加载它,因为这会浪费时间并耗尽闪存(我每个会话需要大约 40 个 DNG,所以超过 800 MB)。 我对 Java 不是很熟悉,但是有没有办法覆盖 OutputStream 并添加我自己的 JNI 调用?
假设您有一个可以与 OutputStream 一起使用的 DNG 创建函数,您可以实例化一个 ByteArrayOutputStream,将其作为参数传递给您的 DNG 创建函数,然后通过方法调用获取字节数组 toByteArray()
.
然后可以将其传递给本机 C 库。
在代码中这可能是这样的:
package com.software7.jni;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Main {
private native void transferDng(byte[] data);
private void someDNGCreationFunction(OutputStream outputStream)
throws IOException {
outputStream.write("hello world!".getBytes(UTF_8));
}
private void test() throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
someDNGCreationFunction(baos);
transferDng(baos.toByteArray());
}
}
public static void main(String[] args) {
System.loadLibrary("Native");
Main m = new Main();
try {
m.test();
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后本机端可以从字节数组中检索数据,例如看到这个很好的答案
#include <string.h>
#include <stdlib.h>
#include <jni.h>
#include "com_software7_jni_Main.h"
JNIEXPORT void JNICALL Java_com_software7_jni_Main_transferDng
(JNIEnv *env, jobject obj, jbyteArray dng) {
jsize num_bytes = (*env)->GetArrayLength(env, dng);
jbyte *b = (*env)->GetByteArrayElements(env, dng, 0);
char *buffer = malloc(num_bytes);
memcpy(buffer, b, num_bytes);
(*env)->ReleaseByteArrayElements(env, dng, b, 0);
//do something with the buffer, here a printf only for testing
printf("%.*s", num_bytes, buffer);
free(buffer);
return;
}