Java 从C++;

Java 从C++;,java,c++,java-native-interface,jnienv,Java,C++,Java Native Interface,Jnienv,情况: 我有一个实现JNI的dll,我想从Cpp应用程序调用其中的方法 当前状态: 据我了解,实现JNI的dll实际上与JAVA无关,例如: 在Test.java中,我编写了 public-native-int-Add(int-a,int-b) 并在TestDll.Cpp中用Cpp实现 JNIEXPORT jint JNICALL Java\u SomeNamespace\u Add(JNIEnv*\u Env,jobject\u Object,jint a,jint b) { 返回a+b

情况: 我有一个实现JNI的dll,我想从Cpp应用程序调用其中的方法

当前状态: 据我了解,实现JNI的dll实际上与JAVA无关,例如: 在Test.java中,我编写了
public-native-int-Add(int-a,int-b)

并在TestDll.Cpp中用Cpp实现
JNIEXPORT jint JNICALL Java\u SomeNamespace\u Add(JNIEnv*\u Env,jobject\u Object,jint a,jint b)
{
返回a+b;
}

我认为这样的程序与JVM无关,jint结构似乎已经在jni.h中完全定义好了。
因此,我想知道是否可以直接调用
Java\u SomeNamespace\u Add
,而无需从Cpp应用程序创建VM,如果可以的话:

  • 参数列表中的`JNIEnv*`和`jobject`应该是什么?
  • 如何将'jint'变量转换为标准'int'变量
  • 如何在不使用`_Env->FindClass(“Ljava/lang/string;”)和以下代码的情况下,将`jstring`变量转换为标准`string`变量

  • 一般来说,有一个原因会阻止您在没有Java的情况下加载JNIDLL。DLL可能需要一些JVM外部符号。但是如果你需要的话,你可以用假人来伪装它们

    如果DLL是从Java为您加载的,那就更容易了:您可以毫不畏惧地调用DLL的任何导出函数

    如果导出的JNI方法调用不使用JNIEnv参数(如您的示例
    Add()
    ),您只需传递nullptr即可满足调用约定

    但是,这不允许传递参数,如jstringjarray。在任何情况下,最好的做法是将JNI的各个层与实际逻辑分离,这需要将参数从Java转换为本机


    但是如果您无法控制DLL,您可以尝试完全伪造JNI。请参见jni.h并以适合您的方式实现必要的功能。

    对于第一个问题,我认为只需使用一些重构创建一个简单的替代方案是一个好主意

    < >将算法的逻辑放入JNI调用本身中,将逻辑移动到单独的C++函数,并从两个用例中调用该函数。 即:

    对于数字2,您可以使用标准C样式转换在jint和int之间转换:

    int a = 10;
    jint b = (jint) a;
    int c = (int) b
    
    至于第三点:

    如果您是从JNI内部调用函数,则将使用以下描述的一对函数:

    要将上述C字符串转换为std::string,可以执行以下操作:

    std::string cpp_string = str;
    
    如果您没有使用JNI调用函数,那么看起来您需要尝试并进行自己的转换。我想看看你是否可以使用现有的虚拟机实现,弄清楚他们是如何做到的并模仿它

    例如,您可以尝试使用以下作为起点的Android VM:

    1。它们将是空的。2.jint和int32_t是一回事。3.没有Java JNI代码,jstring无法转换为std::string。。您可以使用JNI创建一个JVM,然后进行转换。@Brandon我可以只包含JNI.h并做一些事情,然后它就神奇地工作了吗?您是否验证了您的实际DLL对
    env
    指针和/或接收器对象或可能的参数对象没有任何作用?我不认为你可以从你的测试函数中概括出来。如果我不能控制那个dll呢?我会尝试创建一个JVM实例。您可以在这里看到如何做到这一点:这将创建一个JNIEnv,供您作为第一个参数传递。我怀疑在大多数情况下,您可以将第二个参数obj保留为NULL。
    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);
    }
    
    std::string cpp_string = str;