获取有效的JNIEnv指针

时间:2016-08-09 23:52:23

标签: java android unity3d dll java-native-interface

我想通过将函数导出到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,而不是相反。

2 个答案:

答案 0 :(得分:2)

我认为您可以创建另一个本机插件,它将为您提供JNIEnv。

Plugins for Android

总结这篇文章你应该试试这样的(未经测试的伪代码)

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变量。

相关问题