java - मान्य JNIEnv पॉइंटर प्राप्त करना




android unity3d (2)

मुझे लगता है कि आप एक और देशी प्लगइन बना सकते हैं जो आपको JNIEnv देगा।

एंड्रॉइड के लिए प्लगइन्स

इस आलेख का सारांश आपको इस तरह से कुछ करने की कोशिश करनी चाहिए (untested छद्म कोड) :

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;
}

फिर सी # में

[DllImport ("PluginName")]
private static extern IntPtr GetJniEnv();

मेरे पास एक सी + + डीएलएल है जो मैं कार्यों को सी # को निर्यात करके यूनिटी में उपयोग करना चाहता हूं। यूनिटी प्रोजेक्ट एंड्रॉइड डिवाइस पर चलता है और सी ++ कोड जावा का उपयोग करता है सी ++ को प्रारंभ करने के लिए मुझे निम्न फ़ंक्शन को पहले कॉल करने की आवश्यकता है:

void api_initialize(JNIEnv* env, jobject* app_context, jobject* class_loader) {

    JavaVM* vm = nullptr;
    env->GetJavaVM(&vm);
    if (!vm) {
      return;
    }

    //Do other proprietary things
}

यूनिटी में मेरे पास निम्न निर्यात डीएलएल फ़ंक्शन है I

    [DllImport (dllName)]
    private static extern void api_initialize (IntPtr java_env, IntPtr app_context, IntPtr class_loader);

मेरा प्रश्न यह है कि मैं अपने सी # वर्ग में एक जेएनआईइएनवी पॉइंटर कैसे प्राप्त करूं, फिर इस फ़ंक्शन में एक पैरामीटर के रूप में पास करूँ?

मैं इस एपीआई के निर्माता नहीं हूं और इसे संशोधित करने की पहुंच नहीं है, इसलिए मुझे जावामेल को जेएनआईईएनवी से प्राप्त करना होगा, अन्य तरह से नहीं।


मुझे लगता है कि ऐसा कोई तरीका नहीं है कि आप ऐसा कर सकते हैं (हो सकता है, लेकिन इसे अभी तक नहीं देखा) क्योंकि इस प्रकार के NDK calls आसपास जावा लपेटन की आवश्यकता होती है, इसलिए मैं उद्देश्य को एक और समाधान चाहूंगा जो जावा का उपयोग आपके सी # के लिए intermediate रूप में करता है। कॉल करें और फिर आप इस कॉल को java से NDK code redirect कर सकते हैं।

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

और आपकी जावा फ़ाइल में ऐसा करें

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()); 
  }
}

जब आप मूल विधि घोषित करते हैं तो javah स्वचालित रूप से एक जावा क्लाइंट परिभाषा को जेवाइएनवी और पैराग्राफ के रूप में नौकरी के साथ जनरेट किया जाता है, तो मुझे लगता है कि आपको केवल क्लास लोडर को पास करने की आवश्यकता है। अधिक स्पष्टीकरण के मामले में आप इस लिंक और इस लिंक्स की कोशिश कर सकते हैं।

अच्छा सौभाग्य। आशा है यह मदद करेगा





jni