Log in or register to post comments

Problem with JNI

March 4, 2011 - 1:04am #1

Hi everyone

I have some problem when I want to send string from .cpp to .java in ImageTarget. I add this on ImagetTarget.cpp

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_stringFromJNI(JNIEnv *env,jobject obj,jstring javaString)                                                
{
	
	return (*env)->NewStringUTF(env, "String send to java class");
}
	

this code has a error but I don't know what the problem.
Thank you

Re: Problem with JNI

March 10, 2011 - 9:06pm #16

Thank you Kim :)

Re: Problem with JNI

March 10, 2011 - 7:51pm #15

That looks like the same problem as before. The strcmp method returns 0 when the strings are equal, so you need to check the result against 0 for the statement to return true:

if(strcmp(trackable->getName(), "entrance") == 0)
{
    textureIndex = 0;
    checksong = 0;
}

- Kim

Re: Problem with JNI

March 10, 2011 - 6:37pm #14

To kim
You mean that if I add 3 texture like that

		mTextures.add(Texture.loadTextureFromApk("newbluedora2.png",
                                                 getAssets()));
		mTextures.add(Texture.loadTextureFromApk("newbluedora2.png",
                getAssets()));
		mTextures.add(Texture.loadTextureFromApk("newreddora2.png",
                                                 getAssets()));

that can add 3 texture

My problem is it not return "checksong " when another trackable (not first and second) in if condition.

Thank you

Re: Problem with JNI

March 10, 2011 - 10:11am #13

I'm not sure I understand the question. The ImageTargets sample only has two textures in the array, because only two textures are created in the java code. Look at the loadTextures() method in ImageTargets.java. Two textures are loaded from the assets folder, and these are the textures that end up in the native array. So, when you call this:

const Texture* const thisTexture = textures[textureIndex];

make sure textureIndex is a value between 0 and the max number of textures you created in java.

- Kim

Re: Problem with JNI

March 10, 2011 - 7:17am #12

To kim

I have some question in Imagetarget that why it can get only 2 texture :confused:

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv *, jobject)
{ ....

			int textureIndex;
			int checksong = 0;

			//if(strcmp(trackable->getName(), "stones"))
			//{
				//textureIndex = 0;
				//checksong = 0;
			//}
			if(strcmp(trackable->getName(), "entrance"))
			{
				textureIndex = 0;
				checksong = 0;
			}
			else if(strcmp(trackable->getName(), "classroom"))
			{
				textureIndex = 1;
				checksong = 1;
			}
			else if(strcmp(trackable->getName(), "auditorium"))
			{
				textureIndex = 2;
				checksong = 2;
			}
			else if(strcmp(trackable->getName(), "BitandByte"))
			{
				textureIndex = 3;
				checksong = 3;
			}
			else if(strcmp(trackable->getName(), "firstaid"))
			{
				checksong = 4;
			}

const Texture* const thisTexture = textures[textureIndex];

                if(checksong == 0) // entrance
               {
                     check = 1;
                }

		else if (checksong == 1) // classroom
		{
			check = 2;
		}
		else if (checksong == 2) // auditorium
		{
			check = 3;
		}
		else if (checksong == 3) // bitandbyte
		{
			check = 4;
		}
...

}
JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_GUIManager_stringFromJNI2(JNIEnv *env,jobject obj,jstring javaString)
{
    if (check==1) // entrance
    {
        return env->NewStringUTF("http://u5088014.polppol.com/file/entrance.mp3");
    }
	else if (check==2) // classroom 
	{
		return env->NewStringUTF("http://u5088014.polppol.com/file/third.mp3");
	}
	else if (check==3) // auditorium
	{
		return env->NewStringUTF("http://u5088014.polppol.com/file/auditorium.mp3");
	}
	else if (check==4) // bitandbyte
	{
		return env->NewStringUTF("http://u5088014.polppol.com/file/bitandbite.mp3");
	}
}

The sound can play only check == 1 or check == 2 .
But the model can show in all trackable.

Thank you

Re: Problem with JNI

March 8, 2011 - 8:00pm #11

Thank you Kim for your help :):)

Re: Problem with JNI

March 7, 2011 - 8:33am #10

You should only call QCAR::Renderer::getInstance().begin() from the renderFrame method. In general, you get the state object in the renderFrame method and check the visible trackable name there. Then you can save some information to a global variable like "check" for use in other methods.

Here are some code changes I made that worked:

1) Added a global variable to ImageTargets.cpp:

int check = 0;

2) Added the following method to ImageTargets.cpp:

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_stringFromJNI2(JNIEnv *env,jobject obj,jstring javaString)
{
    if (check==1)
    {
        return env->NewStringUTF("http://u5088014.polppol.com/file/entrance.mp3");
    }
    else
    {
        return env->NewStringUTF("Nothing visible");
    }
}

3) Added some code to the renderFrame method in ImageTargets.cpp:


JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv *, jobject)
{
    check = 0;
    
    ...
    
    // Did we find any trackables this frame?
    for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)
    {
        // Get the trackable:
        const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);
        QCAR::Matrix44F modelViewMatrix =
            QCAR::Tool::convertPose2GLMatrix(trackable->getPose());        

        // Choose the texture based on the target name:
        int textureIndex = (!strcmp(trackable->getName(), "stones")) ? 0 : 1;
        const Texture* const thisTexture = textures[textureIndex];
        
        if(strcmp(trackable->getName(), "stones") == 0)
        {
            check = 1;
        }
        
        ...
    }
    
    ...
    
    QCAR::Renderer::getInstance().end();
}

4) Added the native method signature to ImageTargetsRenderer.java:

public native String stringFromJNI2(String s);

5) Added a call to stringFromJNI2 just after the renderFrame method is called in ImageTargetRenderer.java:

public void onDrawFrame(GL10 gl)
{
    if (!mIsActive)
        return;

    // Call our native function to render content
    renderFrame();
    
    DebugLog.LOGI("string from native: " + stringFromJNI2("test"));
}

You can see the output in the log, switch to the DDMS perspective in Eclipse and look at the LogCat view.

You can call the stringFromJNI2 native method from another Java class, just be sure to update the native method signature with the new class name:

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_MyJavaClass_stringFromJNI2(JNIEnv *env,jobject obj,jstring javaString)

- Kim

Re: Problem with JNI

March 7, 2011 - 8:01am #9

To Kim:
You mean that method renderFrame return interger to ImageTargetsRenderer.java ??

I have another question about get name of trackable that can call only once in imageTarget.cpp

I can call in other function because when I use trackable->getname in this

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_GUIManager_stringFromJNI(JNIEnv *env,jobject obj,jstring javaString)                                                
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

QCAR::State state = QCAR::Renderer::getInstance().begin();

 for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)
 {
	if(strcmp(trackable->getName(), "stones"))
	{
		return env->NewStringUTF("http://u5088014.polppol.com/file/entrance.mp3");
	}
	else if(strcmp(trackable->getName(), "entrance"))
	{
		return env->NewStringUTF("http://u5088014.polppol.com/file/computer_lab.mp3");
	}
}

}

Can I declare again in another function when I want to get name of trackable

Thank you

Re: Problem with JNI

March 7, 2011 - 6:59am #8

The strcmp method returns 0 when the strings are equal, so you probably want to do this check instead:

if(strcmp(trackable->getName(), "stones") == 0)

Also, make sure that you are calling the native method from the GUIManager class, since you are using this class name in the method signature.

Finally, make sure you are resetting check to 0 at the beginning of the renderFrame method.

- Kim

Re: Problem with JNI

March 6, 2011 - 8:43pm #7

JNI can sent value between class.
My problem is when detect the trackable the value not sent to another class like
the code that I posted.
I want to sent check=1 when camera detect the trackable.

if(strcmp(trackable->getName(), "stones"))
{
	textureIndex = 0;
	check = 1;

}

This is another class

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_GUIManager_stringFromJNI(JNIEnv *env,jobject obj,jstring javaString)                                                
{
     if(check==1)
{
	return env->NewStringUTF("http://u5088014.polppol.com/file/entrance.mp3");
}

Thank you

Re: Problem with JNI

March 6, 2011 - 6:48pm #6

This looks like a simple syntax error to me, I think you mean to use this:

if(check==1)

instead of this:

if(check=1)

Happens to all of us at one point or another :)

- Kim

Re: Problem with JNI

March 5, 2011 - 7:45am #5

I have some another problem with JNI to send parameter from class in JNI to another class in JNI. (Can see code below)
Send from this

int check;
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv *, jobject)
{
...
int textureIndex=0;
if(strcmp(trackable->getName(), "stones"))
{
	textureIndex = 0;
	check = 1;

}
else if(strcmp(trackable->getName(), "entrance"))
{
	textureIndex = 1;
        check = 2;

}
.....
}

To this class

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_GUIManager_stringFromJNI(JNIEnv *env,jobject obj,jstring javaString)                                                
{
     if(check=1)
{
	return env->NewStringUTF("http://u5088014.polppol.com/file/entrance.mp3");
}else if(check=2)
{
	return env->NewStringUTF("http://u5088014.polppol.com/file/computer_lab.mp3");
}

	   

	
}

I will try this but the value cannot send. Because it alway return the first one ever check are 1 or 2;

Thank you

Re: Problem with JNI

March 4, 2011 - 9:47am #4

thank you kim:)

Re: Problem with JNI

March 4, 2011 - 7:23am #3

You should be able to return a string via JNI, try this syntax instead:

JNIEXPORT jstring JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_stringFromJNI(JNIEnv *env,jobject obj,jstring javaString)                                                
{
    return env->NewStringUTF("String send to java class");
}

Then, be sure to use the right method signature in ImageTargets.java:

public native String stringFromJNI(String s);

- Kim

Re: Problem with JNI

March 4, 2011 - 1:55am #2

Hello,

If you want to pass a string to the java code, check out this thread it has sample code:

http://ar.qualcomm.at/node/2000032

Log in or register to post comments