我想通过将函数导出到C#来在Unity中使用C ++ dll。 Unity项目在Android设备上运行,C ++代码使用java。要初始化C ++,我需要先调用以下函数:
void api_initialize(JNIEnv* env, jobject* app_context, jobject* class_loader) {
JavaVM* vm = nullptr;
env->GetJavaVM(&vm);
if (!vm) {
return;
}
//Do other proprietary things
}
在Unity中,我有以下导出的Dll函数
[DllImport (dllName)]
private static extern void api_initialize (IntPtr java_env, IntPtr app_context, IntPtr class_loader);
我的问题是如何在我的C#类中获取JNIEnv指针然后作为参数传递给此函数?
我不是这个API的创建者,也没有权限修改它,所以我需要从JNIEnv获取JavaVM,而不是相反。
答案 0 :(得分:2)
我认为您可以创建另一个本机插件,它将为您提供JNIEnv。
总结这篇文章你应该试试这样的(未经测试的伪代码):
JavaVM* g_JVM; // JavaVM is valid for all threads, so just save it globally
extern "C" {
JNIEnv* GetJniEnv();
}
// The VM calls JNI_OnLoad when the native library is loaded
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
g_JVM = vm;
return JNI_VERSION_1_6;
}
// The JNI interface pointer (JNIEnv) is valid only in the current thread.
JNIEnv* GetJniEnv() {
JNIEnv* jni_env = 0;
g_JVM->AttachCurrentThread(&jni_env, 0);
return jni_env;
}
然后在C#
[DllImport ("PluginName")]
private static extern IntPtr GetJniEnv();
答案 1 :(得分:0)
扩展Vyacheslav Gerasimov的回答,此代码经过测试并无需任何额外工作即可完成:
JNIEnv* jni_env = NULL;
JavaVM* JVM;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JVM = vm;
if (vm->GetEnv((void**)&jni_env, JNI_VERSION_1_6) != JNI_OK)
__android_log_print(ANDROID_LOG_ERROR, "Unity", "ERROR: GetEnv failed")
return JNI_VERSION_1_6;
}
Unity / Java自动调用JNI_OnLoad
不需要C#,因为您可以在c ++中传递jni_env或JVM变量。