Jump to content
  • Advertisement
Sign in to follow this  
_WeirdCat_

call a java void from android ndk

This topic is 1003 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

		AnsiString ahue = "";
		if ( (apply_to->scriptlen > 0) || (apply_to->script != NULL)) ahue = apply_to->script;
		JNIEnv * env = NULL;
		int status;
		status = ANDROID_ENVIROMENT->GetEnv((void **)&env, JNI_VERSION_1_6);
		if(status < 0) ALOG("CANT FIND ENVIROMENT");
		ANDROID_ENVIROMENT->AttachCurrentThread(&env, NULL);
		if(status < 0) ALOG("CANT ATTACH THREAD");
		jstring jstr = env->NewStringUTF(ahue.c_str());
		jclass activityClass = env->FindClass("com/example/wirednavalbattle/MainActivity");
		if (activityClass == NULL) ALOG("CLASS IS NULL");
		jmethodID MemoScript = env->GetMethodID(activityClass, "ScriptMemo", "(Ljava/lang/String;)V");
if (MemoScript == NULL) ALOG("WRONG METHOD");

		env->CallVoidMethod(activityClass, MemoScript, jstr); <-- it breaks here
java code

	public void ScriptMemo(String text)
	{
		finish();  

	}

how i init ANDROID_ENVIROMENT var

JNIEXPORT void JNICALL Java_com_example_wirednavalbattle_GameLibJNIWrapper_PSetEnviroment(JNIEnv * env, jclass cls, jint str)
{
	 JavaVM* jvm;
	 env->GetJavaVM(&jvm);
	MakeEnv(jvm); //cal in the same h file
}

void MakeEnv(JavaVM * jvm)
{
	SetAppEnviroment(jvm); //call in diffrent h file
}

void SetAppEnviroment(JavaVM* jvm)
{
ANDROID_ENVIROMENT = jvm;
}





//now in java when i have my class extends Activity

i overrride onCreate function and place there

THE_RENDER_WRAPPER.NMBSetEnv(0); //set enviroment this calls the function on top

error is:

 

 

12-16 02:05:36.140: A/libc(16315): Fatal signal 11 (SIGSEGV) at 0x000002d3 (code=1), thread 16315 (irednavalbattle)

12-16 02:05:36.250: I/DEBUG(137): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
12-16 02:05:36.250: I/DEBUG(137): Build fingerprint: 'orange_pl/ST26i_1267-4750/ST26i:4.1.2/11.2.A.0.31/07_96g:user/release-keys'
12-16 02:05:36.250: I/DEBUG(137): pid: 16315, tid: 16315, name: irednavalbattle  >>> com.example.wirednavalbattle <<<
12-16 02:05:36.250: I/DEBUG(137): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 000002d3

 

 

12-16 02:05:36.520: I/DEBUG(137):     #00  pc 00069ff0  /system/lib/libdvm.so (dvmGetVirtualizedMethod(ClassObject const*, Method const*)+75)

12-16 02:05:36.520: I/DEBUG(137):     #01  pc 0004cf7d  /system/lib/libdvm.so
12-16 02:05:36.520: I/DEBUG(137):     #02  pc 0005c3d8  /data/data/com.example.wirednavalbattle/lib/libgame.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+60)

 

 

12-16 02:05:36.530: I/DEBUG(137):          be99a154  537a03dc  /data/data/com.example.wirednavalbattle/lib/libgame.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+64)

looks more like bad address taken, i have no idea why ;x

Edited by WiredCat

Share this post


Link to post
Share on other sites
Advertisement

		env->CallVoidMethod(activityClass, MemoScript, jstr); <-- it breaks here

The first argument to CallVoidMethod() is the instance you are calling it on, not the class.

Share this post


Link to post
Share on other sites

You just get the jclass of your main activity and try to send it in. That's not possible. You need the jobject of your main activity (the actual instance, not just the class type)

To get that, you need to pass it down to your C++ code somehow, you can't get it with JNI code only.

 

I do it by passing down the activity as an argument when initializing the JNI part of my application

 

 

Here is the page I use when I wonder about any JNI call: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

But remembering that when using it in C++, the first "env" argument is removed on all calls.

Edited by Olof Hedman

Share this post


Link to post
Share on other sites
Note that you can call a static void method the way you are attempting (although you would need to use CallStaticVoidMethod()).

A non-static method always requires a an object reference to satisfy the implicit this argument.

Share this post


Link to post
Share on other sites

this is bulls***, i dont even know what kind of jobject is in java, i stop implementing text editor for script editing in java (i just wanted a stupid text field and retreive its text)

 

its way easier for me to add {} () ; <> = buttons as new keyboard layout for my opengl text editor rather that screwing with cesspol called java

Share this post


Link to post
Share on other sites


this is bulls***, i dont even know what kind of jobject is in java

All java objects are derived from java.lang.Object, so you can treat jobject as pointer to most common base.

And you're too c++ -centric. What you got by calling env->FindClass() is something similar to c++'s typeinfo.

Yes, it's also object, but that's the instance of typeinfo class, and not the instance of MainActivity class.

If your native methods doesn't belong to main activity class, you'll have to pass main activity instance explicitly to that native method.

If it was main activity's method, you'd get reference to activity instance as second argument to native method ("this" pointer).

 

Note that there's other possible causes to crash.

If you're calling that method not from Java thread, but from native thread, then class might be not found, since android will try search desired class from class loader, found by tracing stack.

Also take note, that if FindClass() failed, it will raise exception. Exception state should be explicitly checked and cleared, otherwise jni code will crash on next call to java.

Share this post


Link to post
Share on other sites


i dont even know what kind of jobject is in java, i stop implementing text editor for script editing in java ... its way easier for me to add {} () ; <> = buttons as new keyboard layout for my opengl text editor
The problem is not with Java. It is endemic to software development and to learning new systems generally.

 

If you know what piece to add it is quick and easy. Adding a simple piece of code to a well-written system is generally straightforward. Adding a new piece of data to a well-written system is also generally straightforward.

 

But if you don't know those details, adding a new piece can be very difficult.  That is part of the learning curve.

 

It is hard before you've mastered it and when using poorly-architected systems. Once you've mastered the system you can start building well-architected systems, and convert your poorly-architected systems into better ones. And once you've got those, extending it becomes quick easy.

Share this post


Link to post
Share on other sites

It's also worth pointing out that Android's NDK support isn't really designed for writing pure C++ applications (although there is minimal support for that use-case).

 

It's really meant to allow Java applications to call out to native code. You'll generally find you have a much easier time of things if you bootstrap everything with a Java app, and then handoff to native for the game logic and any performance critical areas like rendering and physics.

 

This means that control always flows from Java -> C++, and you almost never end up needing to call back up into Java methods. All your JNI methods can be neatly encapsulated as static methods in a wrapper class, and like becomes a much happier place.

Share this post


Link to post
Share on other sites

yeah but i am even unable to call public static void ShowTextEditor()

{

javacrap here <- cannot call nonstatic from static some thing like that 

}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!