英文:
JNI pass interface as function to CPP code
问题
我有一个在CPP代码中定义的函数,如下:
using Data = std::vector<byte>;
void sign(const std::function<Data(Data)> externalSigner) {
...
}
我需要将Java接口作为参数传递给这个函数。
public interface ByteArrayProvider {
byte[] provide(byte[] data);
}
我能够找到我的接口,调用它并获取结果。但我不知道如何将它传递给C++函数。
英文:
I have a function in CPP code which is defined as
using Data = std::vector<byte>;
void sign(const std::function<Data(Data)> externalSigner) {
...
}
And I need to pass java interface as a parameter to this function.
public interface ByteArrayProvider {
byte[] provide(byte[] data);
}
I'm able to find my interface, call and get result. But I can't figure out how to pass it to C++ function.
答案1
得分: 2
NativeLib.java:
package com.example.nativelib;
public class NativeLib {
static { System.loadLibrary("nativelib"); }
public static native void sign(ByteArrayProvider bap);
}
nativelib.cpp:
#include <jni.h>
#include <vector>
Data myFunc(JNIEnv* env, jobject bap, Data data) {
jbyteArray a = env->NewByteArray(data.size());
env->SetByteArrayRegion(a, 0, data.size(), (const jbyte*)data.data());
jclass cls = env->GetObjectClass(bap);
jmethodID provide = env->GetMethodID(cls, "provide", "([B)[B");
jbyteArray aret = (jbyteArray)env->CallObjectMethod(bap, provide, a);
jbyte* bytes = env->GetByteArrayElements(aret , 0);
std::vector<char> ret(bytes, bytes + env->GetArrayLength(aret));
env->ReleaseByteArrayElements(aret, bytes, JNI_ABORT);
return ret;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_nativelib_NativeLib_sign(JNIEnv* env, jclass clazz, jobject data) {
sign(std::bind(myFunc, env, data, std::placeholders::_1));
}
Then you can simply call (bap is your ByteArrayProvider):
NativeLib.sign(bap);
英文:
First you have to create a new native library inside your project under File > New > New Module... > Android Native Library
. I selected Java as language.
NativeLib.java:
package com.example.nativelib;
public class NativeLib {
static { System.loadLibrary("nativelib"); }
public static native void sign(ByteArrayProvider bap);
}
nativelib.cpp:
#include <jni.h>
#include <vector>
Data myFunc(JNIEnv* env, jobject bap, Data data) {
jbyteArray a = env->NewByteArray(data.size());
env->SetByteArrayRegion(a, 0, data.size(), (const jbyte*)data.data());
jclass cls = env->GetObjectClass(bap);
jmethodID provide = env->GetMethodID(cls, "provide", "([B)[B");
jbyteArray aret = (jbyteArray)env->CallObjectMethod(bap, provide, a);
jbyte* bytes = env->GetByteArrayElements(aret , 0);
std::vector<char> ret(bytes, bytes + env->GetArrayLength(aret));
env->ReleaseByteArrayElements(aret, bytes, JNI_ABORT);
return ret;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_nativelib_NativeLib_sign(JNIEnv* env, jclass clazz, jobject data) {
sign(std::bind(myFunc, env, data, std::placeholders::_1));
}
Then you can simply call (bap is your ByteArrayProvider):
NativeLib.sign(bap);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论