I have a C++ dll that I want to use in Unity by exporting the functions to C#. The Unity project runs on Android devices and the C++ code makes use of java. To initialize the C++ I need to call the following function first:
void api_initialize(JNIEnv* env, jobject* app_context, jobject* class_loader) {
JavaVM* vm = nullptr;
env->GetJavaVM(&vm);
if (!vm) {
return;
}
//Do other proprietary things
}
In Unity I have the following exported Dll function
[DllImport (dllName)]
private static extern void api_initialize (IntPtr java_env, IntPtr app_context, IntPtr class_loader);
My question is How do I get a JNIEnv pointer in my C# class to then pass as a parameter into this function?
I am not the creator of this API and don't have the access to modify it, so I need to get the JavaVM from the JNIEnv, not the other way around.
jobject NewGlobalRef(JNIEnv *env, jobject obj); Creates a new global reference to the object referred to by the obj argument. The obj argument may be a global or local reference.
It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.
Introduction to Java Native Interface: Establishing a bridge between Java and C/C++ JNI (Java Native Interface) is a foreign function interface that allows code running on JVM to call (or be called by) native applications. Using JNI, one can call methods written in C/C++ or even access assembly language.
I guess there is no way you can do this (might be there but haven't seen it yet) because this type of NDK calls
required java wrapping around so i would like to purpose an another solution that use Java as an intermediate
for your C# calls and then you can redirect
this call to NDK code
from 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
And in your java file do this
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());
}
}
When you declare native method the javah
automatically generate a ndk call definition with javaEnv and jobject as parameter so i guess you only need to pass class loader here .You can try this link and this links in case for more clarification.
Good Luck.Hope This will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With