获取有效的JNIEnv指针

use*_*677 16 java dll java-native-interface android unity-game-engine

我有一个C++ DLL,我想通过将函数导出到C#来在Unity中使用.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
}
Run Code Online (Sandbox Code Playgroud)

在Unity中,我有以下导出的Dll函数

    [DllImport (dllName)]
    private static extern void api_initialize (IntPtr java_env, IntPtr app_context, IntPtr class_loader);
Run Code Online (Sandbox Code Playgroud)

我的问题是如何在我的C#类中获取JNIEnv指针然后作为参数传递给此函数?

我不是这个API的创建者,也没有修改它的权限,所以我需要从JNIEnv获取JavaVM,而不是相反.

Pav*_*ngh 5

我想你没有办法做到这一点(可能在那里,但还没有看到),因为这种类型NDK calls需要 java 环绕,所以我想使用另一个解决方案,使用 Java 作为intermediate你的 C# 调用,然后您可以redirect致电NDK codefrom java

using UnityEngine;
using System.Collections;
using System.IO;

#if UNITY_ANDROID
public class JavaCallPlugin {

  // Avoid invalid calls
  public static void initiateNDK() {
    if (Application.platform != RuntimePlatform.Android)
          return;

    var pluginClass = 
        new AndroidJavaClass("com.package.class.UnityJavaDelegate");
    AndroidJavaObject plugin = 
        pluginClass.CallStatic<AndroidJavaObject>("obj");
    return plugin.Call("javaCallToNDK");
  } 
}
#endif
Run Code Online (Sandbox Code Playgroud)

然后在你的java文件中执行以下操作

package com.package.class;

import android.content.ContentValues;
import android.content.Intent;
import android.os.Environment;

public class UnityJavaDelegate{
  private static UnityJavaDelegate obj;

  // define function call to your NDK method with native keyword
  private native void api_initialize(); 

  static {
    System.loadLibrary("yourlibraryname"); // setup your ndk lib to use 
  }

  public static UnityJavaDelegate getObj() {
    if(m_instance == null)
       obj= new UnityJavaDelegate();
    return obj;
  }

  private UnityJavaDelegate(){
  }

  public void javaCallToNDK(){
    // this call may not work because i haven't passed class 
    // loader TO NDK before, if not then you should try links 
    // at the bottom of the post to know how to pass customize 
    // as parameter to NDK.

    // put your call to NDK function here 
    api_initialize(this.getClass().getClassLoader()); 
  }
}
Run Code Online (Sandbox Code Playgroud)

当您声明本机方法时,会javah自动生成一个以 javaEnv 和 jobject 作为参数的 ndk 调用定义,所以我想您只需要在此处传递类加载器。您可以尝试此链接链接,以获取更多说明。

祝你好运。希望这会有所帮助。