Search code examples
javaandroidc++android-ndkjava-native-interface

My native method isn't being found by the Java end


My native method isn't being found by the Java end

My subclass of Activity has:

package com.dumb_dumber.myproject;

public class SubActivity extends SDLActivity {//which extends Activity

    private static native void nativeInitGPGS(SubActivity act);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        instance = this;
        nativeInitGPGS(this);
    }

While main.cpp begins, after first preprocessing directives:

extern "C"
{
JNIEXPORT void
Java_com_dumb_1dumber_myproject_SubActivity_nativeInitGPGS(JNIEnv* env, jobject thiz, jobject activity)
{

I know I've inserted a 1 to make it dumb_1dumber, that's what Javah told me to do and has worked in the past, with a different framework. I've tried removing the 1 to no effect.

Still I get:

10-17 16:12:38.051: D/dalvikvm(4980): Trying to load lib /data/data/com.dumb_dumber.myproject/lib/libmain.so 0x423849c8
10-17 16:12:38.055: D/dalvikvm(4980): Added shared lib /data/data/com.dumb_dumber.myproject/lib/libmain.so 0x423849c8
10-17 16:12:38.060: V/SDL(4980): onCreate():null
10-17 16:12:38.087: W/dalvikvm(4980): No implementation found for native Lcom/dumb_dumber/myproject/SubActivity;.nativeInitGPGS:(Lcom/dumb_dumber/myproject/SubActivity;)V
10-17 16:12:38.108: D/AndroidRuntime(4980): Shutting down VM
10-17 16:12:38.108: W/dalvikvm(4980): threadid=1: thread exiting with uncaught exception (group=0x41b73908)
10-17 16:00:52.456: E/AndroidRuntime(4699): FATAL EXCEPTION: main
10-17 16:00:52.456: E/AndroidRuntime(4699): java.lang.UnsatisfiedLinkError: Native method not found: com.dumb_dumber.myproject.SubActivity.nativeInitGPGS:(Lcom/dumb_dumber/myproject/SubActivity;)V
10-17 16:00:52.456: E/AndroidRuntime(4699): at com.dumb_dumber.myproject.SubActivity.nativeInitGPGS(Native Method)
10-17 16:00:52.456: E/AndroidRuntime(4699): at com.dumb_dumber.myproject.SubActivity.onCreate(SubActivity)

I believe the native implementation can be placed anywhere and automagickly picked up. I've tried placing the C implementation in another cpp body, instead of main.cpp but nothing changes.

Here is my Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := main

SDL_PATH := ../SDL

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include

LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
                    main.cpp
#Other stuff removed for clarity

LOCAL_SHARED_LIBRARIES :=   SDL2_image \
                            SDL2    \
                            SDL2_ttf
LOCAL_WHOLE_STATIC_LIBRARIES += gpg_static

LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lz

include $(BUILD_SHARED_LIBRARY)

While I leave loading of the shared libraries to SDLActivity

static {
    System.loadLibrary("SDL2");
    System.loadLibrary("SDL2_image");
    System.loadLibrary("SDL2_ttf");
    System.loadLibrary("main");
}

It's taken me ages to get here and I've built a lot of nice cpp in anticipation of a satisfactory solution but I realise it might not be possible, not by me at least. I've remembered to run ndk-build (twice) in the jni directory and am attempting to run on my phone.

I've run my libmain.so through a hexeditor and can confirm it exists, with the _1 in place. Not much more I can try, but having the time to experiment a little means I can try dropping the underscore. Tried it now, again, no difference.

Here's the first six lines output from nm, thanks Alex,

    U IMG_Init  
    U IMG_Load  
    U IMG_Quit  

00065454 T JNI_OnLoad
0005c208 T Java_org_libsdl_app_SDLActivity_nativeInit
0006851c T Java_com_dumbdumber_myproject_SubActivity_nativeInitGPGS

                            ^^^^^^^^^ 

UPDATE Yep thanks again Chris, myproject was ommitted after you flagged my original activity type name / jobject parameter.


Solution

  • Java_com_dumb_1dumber_myproject_SubActivity_nativeInitGPGS
    

    does not match

    package com.dumb_dumber.myproject;
    
    public class SubActivity extends SDLActivity {//which extends Activity
    
       private static native void nativeInitGPGS(AnagrActivity act);
    

    Hence the no implementation found error.

    Remove the extraneous "1" from your native method name. Also consider choosing a more reasonable package name without an underscore in it.

    I've run my libmain.so through a hexeditor and can confirm it exists, with the _1 in place

    Indeed, it would. While your error trace clearly shows that the linker is looking for a function without that extraneous character. Perhaps this is a quirk of implementation difference between Java vs Dalvik or ART - regardless, you experience it only as a result of an unnecessarily novel package name.