0

I'd like to start by saying please don't ask me to use the javah tool, I've had more luck writing the few jni function prototypes than getting that tool to work properly.

I know that I am loading my jni libraries properly because they work when I leave the class structure the same.

I have some package name: package com.bb.me;

public class test {

  test2 iTest = null;

  public parent test()
  {
    iTest = new test();
    return iTest;
  }

  //putting my native methods here work just fine
  //public native void init();
  //etc

}

The c jni function prototype for that above function looks like this:

JNIEXPORT void JNICALL Java_com_bb_me_test_init(JNIEnv* e, jobject i) {}

if I break that above function signature by renaming it inita and call the function I get an error like this:

No implementation found for native Lcom/bb/me/test;.init:()V

if on the other hand I move the native function to the inner class like this:

class test2 extends parent {
//public native void init();
}

and then try to call the same function, jni will complain at me a different way about unimplemented function but this time it looks like this:

No implementation found for native Lcom/bb/me/test$test2;.init:()V

I originally thought if I edited the jni function signature to something like this:

JNIEXPORT void JNICALL Java_com_bb_me_test_test2_init(JNIEnv* e, jobject i) {}

that the function would work but it doesn't seem like that's the case.

What does the "$" dollar sign mean in this jni function signature?

No implementation found for native Lcom/bb/me/test$test2;.init:()V

How can I move the location of this native function and update the jni function signatures without using the javah tool?

11
  • Should the C tag be C++? Commented Sep 22, 2015 at 19:05
  • @WeatherVane, JNI code can be written in C, and in fact is different when written in C than when written in C++. I don't see any reason to think that the OP mistagged the question. Commented Sep 22, 2015 at 19:15
  • @John Bollinger I would have changed the tag if I was sure. OP states "The c jni function prototype", which could be C, but continues "on the other hand I move the native function to the inner class like this" class test2 extends parent which is not C. Commented Sep 22, 2015 at 19:25
  • @WeatherVane What!? That's Java and there is the java tag! Commented Sep 22, 2015 at 19:28
  • 1
    @WeatherVane, point taken. I have edited the tags to remove not just [C] but also [android] and [android-ndk], none of which were more than peripherally related to the question. Commented Sep 22, 2015 at 20:10

1 Answer 1

4

I'd like to start by saying please don't ask me to use the javah tool, I've had more luck writing the few jni function prototypes than getting that tool to work properly.

I won't ask you to use javah -- though it's hard not to do -- but I have to at least say that I find that remark surprising. I have found javah very easy to use indeed. If it's not working "properly" for you then I'm inclined to suspect that you have the wrong expectations.

What does the "$" dollar sign mean in this jni function signature?

The $ delimits the simple name of a nested class from the name of the class in which it is nested. This is an aspect of the JVM's internal representation of names, which is what JNI works with.

How can I move the location of this native function and update the jni function signatures without using the javah tool?

You could refer to Oracle's documentation for mapping Java native method names to C function names. The expected native function name is based on the fully-qualified JVM name of the native method's class, on the native method's unqualified name, and, if it's overloaded, on its signature. If you move a native method to a different class then you need to alter the function name to reflect the new location, and it is possible that you will also need to encode the function signature into the name if that was not already done.

The JVM name of your inner class is com/bb/me/test$test2. Supposing that the method is not overloaded, the C function name corresponding to the native method residing in that class would therefore be Java_com_bb_me_test_00024test2_init(). The arguments are a different story -- they depend on the arguments to the Java-side method as well as on whether the native method is static. I do not address them here.

Sign up to request clarification or add additional context in comments.

1 Comment

this was it and after some testing i was finally able to get javah to work by using the -clashpath to both the bin/classes folder as well as the location to my android-sdk/anroid.jar file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.