包裹C++;Java中的可调用函数
TL;DR我正试图通过JNI向Java发送一个包裹C++;Java中的可调用函数,java,android,c++,android-ndk,wrapper,Java,Android,C++,Android Ndk,Wrapper,TL;DR我正试图通过JNI向Java发送一个std::function,并在执行异步方法后将其用作Callable(请参见下面的SBCallable)。有没有办法做到这一点? 我尝试通过JNI启动C++的HTTP请求,得到响应并将其发送回C++。 我的JavaNetworkManager类: RequestQueue queue; //initialised in the constructor private class SBCallable<V> implements Cal
std::function
,并在执行异步方法后将其用作Callable
(请参见下面的SBCallable
)。有没有办法做到这一点?
<>我尝试通过JNI启动C++的HTTP请求,得到响应并将其发送回C++。
我的JavaNetworkManager
类:
RequestQueue queue; //initialised in the constructor
private class SBCallable<V> implements Callable<V>{
private String response;
private int responseCode;
public SBCallable(/**function from c++ to call?**/) {
}
public setResponseCode(int responseCode)
{
this.responseCode = responseCode;
}
public setResponse(String response)
{
this.response = response;
}
public V call() throws Exception {
/**call my c++ function(response_code, response);**/
return null;
}
}
public void get(final String url,
final HashMap<String, String> mHeaders,
final SBCallable<Void> callback)
{
queue.add(new StringRequest(
Request.Method.GET,
url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
callback.setResponseCode(200); /**for test purposes**/
callback.setResponse(response);
callback.call();
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
})
{
@Override
public HashMap<String, String> getHeaders() throws AuthFailureError
{
return mHeaders;
}
});
}
RequestQueue队列//在构造函数中初始化
私有类SBCallable实现了Callable{
私有字符串响应;
私人内部响应代码;
公共可调用的(/**函数从C++调用?**){
}
公共设置响应代码(int响应代码)
{
this.responseCode=responseCode;
}
公共设置响应(字符串响应)
{
这个。反应=反应;
}
public V call()引发异常{
/**调用我的C++函数(响应代码,响应);**
返回null;
}
}
public void get(最终字符串url,
最终HashMap mHeaders,
最终可调用回调)
{
添加(新的字符串请求)(
Request.Method.GET,
网址,
新的Response.Listener(){
@凌驾
公共void onResponse(字符串响应){
试一试{
callback.setResponseCode(200);/**用于测试目的**/
callback.setResponse(response);
callback.call();
}捕获(例外e){
e、 printStackTrace();
}
}
},
新的Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
}
})
{
@凌驾
public HashMap getHeaders()抛出AuthFailureError
{
返回mHeaders;
}
});
}
我的C++网络接口:
void get(const std::string &url,
const std::vector<std::pair<std::string, std::string>> &headers,
std::function<void(int, std::vector<char>)> response_fn)
void get(const std::string和url,
const std::向量和标题,
标准::功能响应(fn)
JNI桥接代码:
// OnCreate, the app is saving a pointer to JVM.
void getHTTP(const std::string &url,
const const std::vector<std::pair<std::string, std::string>> &headers,
std::function<void(int, std::vector<char>)> response_fn_t /**callback function, with response code and content**/)
{
JavaVM* jvm = app.getJVM();
JNIEnv *env;
jvm->GetEnv((void**)&env,JNI_VERSION_1_6);
jobject headersMap = vectorStringPairToJavaHashMap(env, headers); // transforms from vector<pair<string, string>> to HashMap<String,String>
jstring url = env->NewStringUTF(url.c_str());
jclass clazz = env->FindClass("NetworkManager");
jobject object = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
/**HOW DO I WRAP response_fn_t for Java to be able to call it? **/
env->CallObjectMethod(object, env->GetMethodID(clazz, "get", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"), url, headersMap, /**wrapped function here**/);
}
//OnCreate,应用程序正在保存指向JVM的指针。
void getHTTP(const std::string和url,
常量std::向量和标头,
std::函数响应\u fn\u t/**回调函数,带响应代码和内容**/)
{
JavaVM*jvm=app.getJVM();
JNIEnv*env;
jvm->GetEnv((void**)和env,JNI_版本1_6);
jobject headersMap=vectorStringPairToJavaHashMap(env,headers);//从vector到HashMap的转换
jstringurl=env->NewStringUTF(url.c_str());
jclass clazz=env->FindClass(“NetworkManager”);
jobject object=env->NewObject(clazz,env->GetMethodID(clazz,“,”()V”);
/**如何包装响应以使Java能够调用它**/
env->CallObjectMethod(object,env->GetMethodID(clazz,“get”,“(Ljava/lang/String;Ljava/lang/object;Ljava/lang/object;)V),url,headersMap,/**此处包装函数**/);
}
您的问题是什么?你在这个网站上呆的时间够长了,你应该知道得更清楚了。@tambre谢谢你的反馈。我更新了问题,希望现在问题清楚了。如果不是,请让我知道你认为缺少什么,我会很高兴地添加信息堆分配一个拷贝/移动<代码> STD::函数< /C> >,将其地址作为<代码>长< /C> >到java端并将其隐藏在那里,将