情况: 我有一个实现JNI的dll,我想从Cpp应用程序中调用其中的方法。
当前状态:
根据我的理解,实现JNI的dll实际上与JAVA无关,例如:
在Test.java中,我写了
public native int Add(int a,int b);
并在TestDll.Cpp中用Cpp实现
JNIEXPORT jint JNICALL Java_SomeNamespace_Add(JNIEnv* _Env, jobject _Object, jint a, jint b)
{
return a+b;
}
我认为这样的程序与JVM无关, jint 结构似乎已在jni.h中完全定义。
因此,我想知道是否可以在不通过Cpp应用程序创建VM的情况下直接调用Java_SomeNamespace_Add
,如果可以的话,
答案 0 :(得分:1)
通常来说,有一个原因可以阻止您在没有Java的情况下加载JNI DLL。 DLL可能需要一些JVM外部符号。但是,如果需要,您可以用假人伪造它们。
如果为您从Java加载了DLL,则更加简单:您可以轻松地调用DLL的任何导出函数。
如果导出的JNI方法调用未使用JNIEnv参数(例如在var click = 0;
$('#element_0_0').on('click', function(event) {
if(click == 0){
$('#element_0_1').removeClass('animated fadeInDown infinite');
setTimeout(function() {
$('#element_0_1').addClass('animated fadeInDown');
}, 10);
click = 1;
}else{
$('#element_0_1').addClass('animated fadeInDown');
setTimeout(function() {
$('#element_0_1').removeClass('animated fadeInDown infinite')
}, 10);
click = 0;
}
});
的示例中),则只需传递 nullptr 即可满足调用约定。
但这不会让您传递诸如 jstring 或 jarray 之类的参数。无论如何,好的做法是将JNI的层与实际的逻辑分开,这需要将参数从Java转换为本机。
但是,如果您无法控制DLL,则可以尝试完全伪造JNI。请参见 jni.h 并以适合您的方式实现必要的功能。
答案 1 :(得分:1)
对于数字1,我认为最好是使用一些重构来创建一个简单的替代方案。
不要将算法的逻辑放入JNI调用本身,而是将逻辑移到单独的c ++函数并从两个用例中调用该函数。
即:
// MyJNIWrapper.cpp
#include "MyMathFunctions.h"
JNIEXPORT jint JNICALL Java_SomeNamespace_Add(JNIEnv* _Env, jobject _Object, jint a, jint b)
{
return (jint)add((int)a, (int)b);
}
// MyMathFunctions.h
int add(int a, int b)
{
return a + b;
}
// MyCppProgram.cpp
#include "MyMathFunctions.h"
int main()
{
int c = add(a, b)
}
对于数字2,您可以使用标准C样式强制转换在jint和int之间转换:
int a = 10;
jint b = (jint) a;
int c = (int) b
第3个:
如果要从JNI内调用函数,则可以使用here中所述的一对函数:
JNIEXPORT void JNICALLJava_MyJavaClass_printName(JNIEnv *env, jobject obj, jstring name)
{
const char *str= (*env)->GetStringUTFChars(env,name,0);
printf(“%s”, str);
//need to release this string when done with it in order to
//avoid memory leak
(*env)->ReleaseStringUTFChars(env, name, str);
}
要从上述C字符串转换为std :: string,可以执行以下操作:
std::string cpp_string = str;
如果您不使用JNI调用该函数,则似乎需要尝试进行自己的转换。我将看看您是否可以使用现有的VM实施方案,弄清楚它们是如何做到的并模仿它。
例如,您可以尝试以这些为起点的Android VM: https://android.googlesource.com/platform/dalvik/+/donut-release/vm/Jni.c#2230 https://android.googlesource.com/platform/dalvik.git/+/android-4.3_r3/vm/UtfString.cpp#284