我寫了以下使用成員指標函式的類:
我寫了以下使用成員指標函式的類。
#include <stdlib.h>/span>
#include <vector>
template<class Type>
class PrimitiveAccessor {
public :
PrimitiveAccessor(
JNIEnv* env, const char name[], const char ctorSig<],
Type (JNIEnv::*callTypeMethodFunction) (jobject, jmethodID)
) {
this->env = env;
this->type = (jclass)env->NewGlobalRef(env->FindClass(name))。
this-> callTypeMethodFunction = callTypeMethodFunction;
}
~PrimitiveAccessor(){
env->DeleteGlobalRef(this->type)。
}
private:
JNIEnv* env;
jclass型別。
jmethodID constructorId。
jmethodID callTypeMethodId。
Type (JNIEnv::*callTypeMethodFunction) (jobject, jmethodID)。
};
class Environment {
public:
Environment(JNIEnv* env) {
this->env = env;
this->init()。
}
~Environment(){
this-> env = 0;
delete(this->jintAccessor) 。
this->jintAccessor = 0;
}
private:
JNIEnv* env;
PrimitiveAccessor<jint>* jintAccessor。
void init() {
jintAccessor = new PrimitiveAccessor<jint> (
env, "java/lang/Integer",
"(I)V", &JNIEnv::CallIntMethod
);
}
};
... 但在編譯時,我得到了以下的編譯錯誤:
F:SharedWorkspacesProjectsDriverFunctionSupplierNative.cpp。在成員函式 'void Environment::init()'。
F:SharedWorkspacesProjectsJNIDriverFunctionSupplierNative。 cpp:75:4: 錯誤:沒有匹配的函式 for呼叫 'PrimitiveAccessor<long int>。 :PrimitiveAccessor(JNIEnv*&, const char [18], const char [5], jint (JNIEnv_::*)(jobject, jmethodID, . . ...)'
);
^
F:SharedWorkspacesProjectsJNIDriverFunctionSupplierNative.cpp:36:3:注意:候選。'PrimitiveAccessor<Type>::PrimitiveAccessor(JNIEnv*, const char*, const char*, Type (JNIEnv_::*)(jobject, jmethodID)) [with Type = long int; JNIEnv = JNIEnv_; jobject = _jobject*; jmethodID = _jmethodID*]'/span>
PrimitiveAccessor(
^~~~~~~~~~~~~~~~~
F:SharedWorkspacesProjectsJNIDriverFunctionSupplierNative.cpp:36:3: 注意:沒有已知的轉換for引數4從'jint (JNIEnv_::*)(jobject, jmethodID, ... )' {aka 'long int (JNIEnv_::*)(_jobject*, _jmethodID*, ... )'}到'long int (JNIEnv_::*)(jobject, jmethodID)'{aka 'long int (JNIEnv_::*)(_jobject*, _jmethodID*)'}.
F:SharedWorkspacesProjectsJNIDriverFunctionSupplierNative.cpp:34:7:注意:候選。'constexpr PrimitiveAccessor<long int>::PrimitiveAccessor(const PrimitiveAccessor<long int>&)'/span>
class PrimitiveAccessor {
^~~~~~~~~~~~~~~~~
... 我通過對成員函式指標的鑄造暫時解決了這個問題:
void init(){
jintAccessor = new PrimitiveAccessor<jint> (
env, "java/lang/Integer",
"(I)V", (long (JNIEnv::*) (jobject, jmethodID))&JNIEnv::CallIntMethod
);
}
... 我注意到,傳遞給模板的型別被擴展了:有什么方法可以避免這種鑄造嗎?
uj5u.com熱心網友回復:
你需要指定一個匹配的型別,而不是一個相似的型別。
我也清理了很多你的不規范的C 。不要使用new,它不是必需的。如果你的資料成員能自我清理,你就不需要一個用戶定義的析構器。你應該在成員初始化器串列中初始化你的資料成員,而不是在建構式的主體中。對于字串,請使用std::string。
#include <stdlib.h>/span>
#include <vector>
#include < memory>
#include <string>
結構 GlobalRefDeleter {
JNIEnv* env;
void operator()(jobject type) {
env->DeleteGlobalRef(type)。
}
};
using JClass = std::unique_ptr<_jclass, GlobalRefDeleter> 。
JClass getClass(JNIEnv* env, const std::string & name) {
return { static_cast<jclass> (env->NewGlobalRef(env->FindClass(name. c_str()))), env };
template<class Type>
class PrimitiveAccessor {
using CallMethod = Type (JNIEnv::*) (jobject, jmethodID, ...)。
public :
PrimitiveAccessor(
JNIEnv* env, const std::string & name, const std::string & ctorSig,
CallMethod callMethod)
) : env(env), type(getClass(env, name)), callMethod(callMethod
{
}
private:
JNIEnv* env;
JClass型別。
jmethodID constructorId。
jmethodID callTypeMethodId。
CallMethod callMethod。
};
class Environment {
public:
Environment(JNIEnv* env) 。env(env), jintAccessor(env, "java/lang/Integer", "(I)V", & JNIEnv: :CallIntMethod)
{
}
private:
JNIEnv* env;
PrimitiveAccessor<jint> jintAccessor。
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316134.html
標籤:
