我正在尝试实现将互斥对象放在地图中的jni函数。 编译时,我得到错误“......因为jni传递一个指针”,我可以在参数中进行转换。
为什么std:map
无法接受指针作为键值?
给出错误的指令是:
std::pair<_jobject , boost::fibers::recursive_mutex> v =
std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
#include <jni.h>
#include <map>
#include "ext_concurrent_fiber_FiberLock.h"
#include <boost/fiber/recursive_mutex.hpp>
std::map<_jobject, boost::fibers::recursive_mutex> mutexes;
boost::fibers::recursive_mutex lock;
// ‘std::pair<_jobject*, boost::fibers::recursive_mutex>::
//pair(_jobject&, boost::fibers::recursive_mutex&)’
// mutexes.insert(std::pair<jobject , boost::fibers::recursive_mutex>((_jobject&)ref, *new boost::fibers::recursive_mutex()));
JNIEXPORT jboolean JNICALL Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent
(JNIEnv * env, jclass clazz, jobject ref){
lock.lock();
std::map<_jobject, boost::fibers::recursive_mutex>::iterator i =mutexes.find(*ref);
if(i == mutexes.end())
{
std::pair<_jobject , boost::fibers::recursive_mutex> v
=std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
mutexes.insert(v);
lock.unlock();
return true;
}
lock.unlock();
return false;
}
下面你可以看到日志:
jni:
[echo] Generating JNI headers
[exec] mkdir -p target/c++
[exec] g++ -c -Wall -fPIC -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux -I/usr/include/boost_1_66_0 -o target/c++/ext_concurrent_fiber_NativeFiber.o src/main/c++/ext_concurrent_fiber_NativeFiber.cpp
[exec] mkdir -p target/c++
[exec] g++ -c -Wall -fPIC -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux -I/usr/include/boost_1_66_0 -o target/c++/ext_concurrent_fiber_FiberLock.o src/main/c++/ext_concurrent_fiber_FiberLock.cpp
[exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp: In function ‘jboolean Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent(JNIEnv*, jclass, jobject)’:
[exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: error: no matching function for call to ‘std::pair<_jobject, boost::fibers::recursive_mutex>::pair(_jobject&, boost::fibers::recursive_mutex&)’
[exec] =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
[exec] ^
[exec] In file included from /usr/include/c++/6/bits/stl_algobase.h:64:0,
[exec] from /usr/include/c++/6/bits/stl_tree.h:63,
[exec] from /usr/include/c++/6/map:60,
[exec] from src/main/c++/ext_concurrent_fiber_FiberLock.cpp:3:
[exec] /usr/include/c++/6/bits/stl_pair.h:423:9: note: candidate: template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>)
[exec] pair(tuple<_Args1...>&, tuple<_Args2...>&,
[exec] ^~~~
[exec] /usr/include/c++/6/bits/stl_pair.h:423:9: note: template argument deduction/substitution failed:
[exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: note: ‘_jobject’ is not derived from ‘std::tuple<_Args1 ...>’
[exec] =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
[exec] ^
[exec] In file included from /usr/include/c++/6/bits/stl_algobase.h:64:0,
[exec] from /usr/include/c++/6/bits/stl_tree.h:63,
[exec] from /usr/include/c++/6/map:60,
[exec] from src/main/c++/ext_concurrent_fiber_FiberLock.cpp:3:
[exec] /usr/include/c++/6/bits/stl_pair.h:356:9: note: candidate: template<class ... _Args1, class ... _Args2> std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>)
[exec] pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
[exec] ^~~~
[exec] /usr/include/c++/6/bits/stl_pair.h:356:9: note: template argument deduction/substitution failed:
[exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: note: ‘boost::fibers::recursive_mutex’ is not derived from ‘std::tuple<_Args1 ...>’
[exec] =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
[exec] ^
答案 0 :(得分:2)
您的问题与指针无关。问题是您尝试在地图中存储的对象类型不可复制,因此您无法构建它们,然后将它们复制到地图中。相反,您可以告诉地图直接在原地构建它们:
std::map<jobject, boost::fibers::recursive_mutex> mutexes;
boost::fibers::recursive_mutex lock;
JNIEXPORT jboolean JNICALL
Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent(JNIEnv* env, jclass clazz, jobject ref)
{
std::lock_guard<boost::fibers::recursive_mutex> lck(lock);
auto i = mutexes.find(ref);
if(i == mutexes.end())
{
mutexes.emplace(std::piecewise_construct,
std::forward_as_tuple(ref),
std::tuple<>{});
return true;
}
return false;
}
在此,我已使用std::map::emplace
和std::pair
std::piecewise_construct
constructor来告诉地图构建其元素。这样,互斥锁就不会被复制到地图中。