How to call native c++ from Java?

I’ve followed yuyu’s tutorial ( updated c3.0) for connecting c++ and Java with JNI. only thing is, it doesn’t cover 3.0 let alone 3.2. i think the distinction is one extend nativeapp,the other Android.
the error i get is"no implementation found for native Luk/co/my project/my activity/app.
what’s with the’L’ prefix, not tutorial.

I use JNI to call C++ from Java and Java from C++

It can be a bit difficult to use at first but it becomes simple after some practice.

Here is a great intro (on Wikipedia of all places LOL)

Sorry for using bad English in OP :~

Original tutorial is http://discuss.cocos2d-x.org/t/updated-v3-0-how-to-connect-c-and-java-with-jni-and-refresh-gui-safely-totorial-1-tutorial-by-yuye/10718 and if you scroll to the bit “JNI in C++” you’ll find v2.x information but nothing on v3.x. I’ve tried the advice of wikipedia, that is prefixing my C++ implementation

extern
"C"
    JNIEXPORT void JNICALL //Java_package name_class name_method name(Arguments,...)

instead of

extern
"C"
{
    void //Java_package name_class name_method name(Arguments,...)

but it’s made no difference. I’m not declaring anything for this in the cpp header file. I’m wondering if I’m putting that extern stuff in the right file. I’ve got a class full of static global functions and I’ve stuck it there, outside the class scope but in the cpp file like a free function, but it’s not being found.

It’s late I know, but here is the code I am actually failing to run:

package com.reallyBadIdea;
import org.cocos2dx.lib.Cocos2dxActivity;

public class BadActivity extends Cocos2dxActivity {
    public static void showPrompt(final String prmptStr) {
        doNowt();
    }

    public static native void doNowt();
}

in GlobStaticFuncs.cpp

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//#include <jni.h>
#include "platform\android\jni\JniHelper.h"
extern
"C"
{
void Java_com_reallyBadIdea_BadActivity_doNowt(JNIEnv* env, jobject thiz) {
    CCLOG("doNowt says Hiya");
}
}
#endif

As far as I understand C++ and JNI, there is no difference in the implementation of for Cocos2d-x 2.x or 3.x, it is a core function of the JVM and native code environment.

This is your .cpp file – because it is extern “C” you do not need a header file. You can put this method into any file you want. The example below is a method that returns a string “OK” or “NOT OK” to the caller based on the arguement.

extern "C" {
  JNIEXPORT jstring JNICALL
  Java_com_tresebrothers_games_factionwars_FactionWarsMainMenu_sendToJNI
  (JNIEnv *env, jobject obj, jint code)
  {
  int iCode = (int)code;
  if(iCode == 0) {
  return env->NewStringUTF("NOT OK");
 }
  return env->NewStringUTF("OK");
        
  }

The other side of the equation is the Java method

 package com.tresebrothers.games.factionwars;
 public class FactionWarsMainMenu extends UtilActivity {

 public native String sendToJNI(int code);

  @Override
protected void onResume() {
	super.onResume();
	String jResponse = sendToJNI(1);
     Log.d(TAG, "Response from C++ was: " + jResponse);
      }
 }

Thanks, I didn’t refresh to get your reply before updating my last post :smile:
It seems I have that code in place (albeit the native method isn’t static- I tried your way since posting, with same result) but when I invoke showPrompt from cocos2dx I still get:

W/dalvikvm(726): No implementation found for native Lcom/reallyBadIdea/BadActivity;.doNowt:()V

I see many people prescribing System.loadLibrary(), but none are using cocos2dx. Can’t hurt to try, and I believe the commensurate java for cocos2dp to be,

    static 
    {
        System.loadLibrary("cocos2dcpp");
    }

I’ve tried javac and javah but they’re complaining about my package naming policy, which I admit to having totally misrepresented in my sample code. Only other non-standard thing I did was to create a custom package name, actually the one I chose initially, com.reallyBadIdea (plus the app name, eg BadApp) which already contained my BuildConfig.java and R.java files.

The debugger keeps landing me in GLSurfaceView.cpp line 1244,

    boolean askedToReleaseEglContext = false;

The compiler is getting my definition because when I implement it elsewhere, ie main.cpp it fails with “previous definition” type errors. Moving to main.cpp didn’t fix it.

The solution!

I’m a bit of skin flint and chose a domain name with a hyphen in it. eg reallybad-idea. Creating a mock up and running it through javah, see https://groups.google.com/forum/#!topic/android-ndk/HC682c2evxI told me this translates to

Java_com_reallyBad_1Idea_BadActivity_doNowt

Java_com_reallyBad_1Idea_BadActivity_doNowt

Yeah, hyphens in Java packages is a bad idea, don’t do that.

I have no idea javah could check headers like that.

Neat trick, I’ve created several hundred JNI integrations and never used that.