JNI在C和C ++中调用不同的东西?

所以我在C中使用以下代码利用Java Native Interface但是我想将其转换为C ++,但我不确定如何。

#include  #include  #include "InstanceMethodCall.h" JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("In C\n"); (*env)->CallVoidMethod(env, obj, mid); } 

Java程序:

  class InstanceMethodCall { private native void nativeMethod(); private void callback() { System.out.println("In Java"); } public static void main(String args[]) { InstanceMethodCall c = new InstanceMethodCall(); c.nativeMethod(); } static { System.loadLibrary("InstanceMethodCall"); } } 

JNI与C和C ++交互的区别是什么? 任何帮助是极大的赞赏。

谢谢,皮特

我曾经有过Essential JNI这本书。 虽然它有点过时,但它的大部分仍然适用于今天。

如果我没记错的话,在C中,Java构造只是指针。 因此,在您的代码中,“ (*env)-> ”取消引用指针,以便您访问基础方法。

对于C ++,“ env ”实际上是一个对象 – 与C指针不同的实体。 (并且JNI实际上可以为您的C ++代码提供实际对象来操作,因为C ++实际上支持对象。)因此“ env-> ”在C ++中具有不同的含义,它意味着“调用由指向的对象中包含的方法” “ env ”。

我相信另一个不同之处在于,许多C-JNI函数要求您的一个参数是“ JNIEnv *env ”。 所以在C中你可能不得不说(*env)->foo(env, bar) 。 使用c ++,第二次引用“ env ”是没有必要的,所以你可以改为说“ env->foo(bar)

不幸的是,我没有在我面前的这本书,所以我不能完全证实这一点! 但我认为调查这两件事(特别是在谷歌或其他JNI代码中寻找它们)会让你走得很远。

您是否尝试在extern "C"包装C代码。 有关更多信息,请参阅C ++ Faq Lite ,以及其他可能允许您将C代码与C ++一起使用的机制。

C和CPP中JNI调用的主要区别在于:

C风格的JNI看起来像(* env) – > SomeJNICall(env,param1 ……)

C ++风格的JNI看起来像env-> SomeJNICall(param1 …)

所以要将它转换为你需要做的CPP

 Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = env->GetObjectClass(obj); jmethodID mid = env->GetMethodID(cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("In C++\n"); env->CallVoidMethod(obj, mid); //rest of your code 

此外,请确保您的JNI函数遵循命名约定。

例:

 JNIEXPORT jint JNICALL Java_com_shark_JNITestLib_JNITestLib_startServer(JNIEnv* env, jobject o, jstring inputName, jstring streamName, jstring description) { 

你可以看到约定是Java_(包名)_(classname)_(methodname)

因为上面的一个用于类似的

 package com.shark.JNITestLib import java.util.stuff; public class JNITestLib { static { System.loadLibrary("myJNIlib"); } public native synchronized int startServer(String inputName, String streamName, String description); //more class stuff... } 

使用JNI时,我将其命名为包含JNI调用的类与该包的名称相同。 这就是为什么你看到JNITestLib两次(这就是为什么我的JNI正常工作,因为我总是忘记如何正确命名JNI调用)

干杯,希望我帮忙:)

自从我触及标准C ++以来已经有一段时间了,但无论如何我都要尝试一下。

(*env)-> ”对我来说很奇怪。 难道不应该只是“ env-> ”吗?

也许我错了,它应该有效,但为什么事情会变得更复杂?

第一个代码是正确的C ++,不是吗? 所以,你已经完成了!

说真的,你想在那段代码中改变什么? 为什么?