c++ JNI将接口作为函数传递给CPP代码

y1aodyip  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(123)

我有一个CPP代码中的函数,定义为

using Data = std::vector<byte>;

void sign(const std::function<Data(Data)> externalSigner) {
   ...
}

而且我需要把java接口作为参数传递给这个函数。

public interface ByteArrayProvider {
    byte[] provide(byte[] data);
}

我可以找到我的接口,调用并得到结果。但是我不知道如何将它传递给C++函数。

4ktjp1zp

4ktjp1zp1#

首先,您必须在项目中的File > New > New Module... > Android Native Library下创建一个新的原生库。
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));
}

然后,您可以简单地调用(bap是您的ByteArrayProvider):

NativeLib.sign(bap);

相关问题