Android ndk:不是有效的ELF可执行文件

时间:2013-12-05 06:13:26

标签: android c++ android-ndk

我正在尝试使用android jni从我的另一个共享库中调用其他一些本机opengl函数。我可以成功编译myegl_jni.so和myegl_impl.so。但是当我试图为myegl_jni.so包含myegl_impl.so时,我收到了这个错误

12-05 09:54:18.802 D/houdini (18259): [18259] Loading library(version: 3.3.1.43195 RELEASE)... successfully.
12-05 09:54:18.802 D/houdini (18259): [18259] Open Native Library /data/app-lib/com.example.nativeegldynamicjni-1/libmyegl_jni.so failed.
12-05 09:54:18.802 E/dalvikvm(18259): dlopen("/data/app-lib/com.example.nativeegldynamicjni-1/libmyegl_jni.so") failed: Cannot load library: load_library(linker.cpp:761): not a valid ELF executable: /data/app-lib/com.example.nativeegldynamicjni-1/libmyegl_jni.so
12-05 09:54:18.802 W/dalvikvm(18259): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/example/nativeegldynamicjni/MainActivity;
12-05 09:54:18.802 W/dalvikvm(18259): Class init failed in newInstance call (Lcom/example/nativeegldynamicjni/MainActivity;)
12-05 09:54:18.802 D/AndroidRuntime(18259): Shutting down VM
12-05 09:54:18.802 W/dalvikvm(18259): threadid=1: thread exiting with uncaught exception (group=0x418dde10)
12-05 09:54:18.802 E/AndroidRuntime(18259): FATAL EXCEPTION: main
12-05 09:54:18.802 E/AndroidRuntime(18259): java.lang.ExceptionInInitializerError
12-05 09:54:18.802 E/AndroidRuntime(18259):     at java.lang.Class.newInstanceImpl(Native Method)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at j ava.lang.Class.newInstance(Class.java:1319)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2313)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.ActivityThread.access$600(ActivityThread.java:144)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.os.Looper.loop(Looper.java:152)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at android.app.ActivityThread.main(ActivityThread.java:5132)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at java.lang.reflect.Method.invokeNative(Native Method)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at java.lang.reflect.Method.invoke(Method.java:511)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at dalvik.system.NativeStart.main(Native Method)
12-05 09:54:18.802 E/AndroidRuntime(18259): Caused by: java.lang.UnsatisfiedLinkError:  Cannot load library: load_library(linker.cpp:761): not a valid ELF executable: /data/app-lib/com.example.nativeegldynamicjni-1/libmyegl_jni.so
12-05 09:54:18.802 E/AndroidRuntime(18259):     at java.lang.Runtime.loadLibrary(Runtime.java:371)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at java.lang.System.loadLibrary(System.java:535)
12-05 09:54:18.802 E/AndroidRuntime(18259):     at com.example.nativeegldynamicjni.MainActivity.<clinit>(MainActivity.java:23)
12-05 09:54:18.802 E/AndroidRuntime(18259):     ... 15 more

我不知道错误在哪里。我是C ++的新手,我猜这个错误可能很容易。请有人帮忙吗?

顺便说一下,我正在使用英特尔x86手机,&#34; Houdini&#34;是英特尔的lib,将arm lib转换为在x86平台上运行。

以下是我的代码:

Android.mk

#Description:makefile of Helloworld  
LOCAL_PATH := $(call my-dir)
#=======================
include $(CLEAR_VARS)

LOCAL_CFLAGS    := -Wall

LOCAL_MODULE    := libmyegl_impl

LOCAL_CPP_EXTENSION := .cpp

#local_ldlibs is used for system libs and does not need dependency
LOCAL_LDLIBS += -llog -lGLESv1_CM

LOCAL_SHARED_LIBRARIES += libcutils libutils

LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)/include 
LOCAL_SRC_FILES := \
        native/MyRendererNative.cpp

LOCAL_CFLAGS:= -DLOG_TAG=\"MyRender\"

include $(BUILD_SHARED_LIBRARY)

#========================

include $(CLEAR_VARS)
LOCAL_CFLAGS    := -Wall

LOCAL_MODULE    := myegl_jni

LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)/include 

LOCAL_CPP_EXTENSION := .cpp

LOCAL_LDLIBS += -llog -lGLESv1_CM

LOCAL_SHARED_LIBRARIES += libmyegl_impl  

LOCAL_SRC_FILES := \
    com_example_nativeegl_MyRenderer.cpp 

include $(BUILD_SHARED_LIBRARY)

# Use the folloing include to make our test apk.
#include $(call all-makefiles-under,$(LOCAL_PATH))

com_example_nativeegl_MyRenderer.cpp

#include "com_example_nativeegl_MyRenderer.h"

extern "C" {
/*
 * Class:     com_example_nativeegl_MyRenderer
 * Method:    nativeGetHelloString
 * Signature: ()Ljava/lang/String;
 */
jstring  nativeGetHelloString(JNIEnv *env, jobject obj) {
      return env->NewStringUTF((char*)" This is calling from JNI suckers!");
  }

/*
 * Class:     com_example_nativeegl_MyRenderer
 * Method:    nativeDrawFrame
 * Signature: ()V
 */
void nativeDrawFrame(JNIEnv *env, jobject obj) {
    renderFrame();
    //myRender->renderFrame();
}

/*
 * Class:     com_example_nativeegl_MyRenderer
 * Method:    nativeSurfaceChanged
 * Signature: (II)V
 */
void nativeSurfaceChanged(JNIEnv *env, jobject obj, jint width, jint height){
    resize(width, height);
    //myRender->resize(width, height);
}


/*
 * Class:     com_example_nativeegl_MyRenderer
 * Method:    nativeSurfaceCreated
 * Signature: ()V
 */
 void nativeSurfaceCreated(JNIEnv *env, jobject obj) {
     //myRender = new MyRender();
     //myRender->init();
     init();
 }

 void init() {
    LOGD("init the renderer");
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f,0.0f, 0.0f, 0.0f);
    glClearDepthf(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 }

 void resize(int width, int height) {
    LOGD("resize the renderer");
    glViewport(0,0, width, height);  //window size
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

 // GLfloat ratio = (GLfloat)width/(GLfloat)height;
    gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
    //glOrthof(-2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f);

    glMatrixMode(GL_MODELVIEW);     // 选择模型观察矩阵
    glLoadIdentity();                         // 重置模型观察矩阵
}

 void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
 {
     GLfloat top = zNear * ((GLfloat) tan(fovy * PI / 360.0));
     GLfloat bottom = -top;
     GLfloat left = bottom * aspect;
     GLfloat right = top * aspect;
     glFrustumf(left, right, bottom, top, zNear, zFar);
}

 void renderFrame() {
    LOGD("renderFrame the renderer");
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
    glLoadIdentity();                   // 重置模型观察矩阵
    glTranslatef(0.0f,0.0f, -6.0f);             // 移入屏幕 6.0

    glRotatef(rtri,0.0f,1.0f,0.0f);             // 绕Y轴旋转金字塔
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(4, GL_FLOAT, 0, gColors);

    glVertexPointer(3, GL_FLOAT, 0, gVertices);
    glDrawArrays(GL_TRIANGLES, 0, 12);
    rtri += 0.2f;                       // 增加三角形的旋转变量
    //LOGI("xxxxx");
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
     glFlush();
 }

 void printGLString(char* name, GLenum s) {
    char *v = (char *) glGetString(s);
    LOGI("GL %s = %s", name, v);
 }

//----------------------------JNI part:Native register------------------------------------------------------
static JNINativeMethod gMethods[] = {
        //{"native method name from Java","(arguments type)return type", "(void*)local_native_name"
        {"nativeGetHelloString", "()Ljava/lang/String;", (void *)nativeGetHelloString},
        {"nativeDrawFrame", "()V", (void *)nativeDrawFrame},
        {"nativeSurfaceChanged", "(II)V", (void *)nativeSurfaceChanged},
        {"nativeSurfaceCreated", "()V", (void *)nativeSurfaceCreated},
};

static const char* className="com/example/nativeegldynamicjni/MyRenderer";

static int registerNativeMethods(JNIEnv *env) {
    jclass clazz;
    clazz = env->FindClass(className);
    if (clazz == NULL) {
        LOGD("failed to load the class %s", className);
        return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
} //end of registerNativeMethods

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
    {
        LOGE("ERROR: GetEnv failed\n");
        goto bail;
    }

    if (registerNativeMethods(env) < 0) {
        LOGE("ERROR: jnitest native registration failed\n");
        goto bail;
    }
    result = JNI_VERSION_1_4;

    bail:
    return result;
}

} //end of extern "C"

MyRenderer.cpp文件

#include "MyRendererNative.h"

MyRenderer::MyRenderer() {

}

MyRenderer::~MyRenderer() {

}

void MyRenderer::printGLString(char* name, GLenum s) {

}
void MyRenderer::init() {

}
void MyRenderer::resize(int width, int height) {

}
void MyRenderer::gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) {

}
void MyRenderer::renderFrame() {

}

我没有附加头文件,因为我觉得它们并不重要。

NDK-构建

编译cpp文件。奇怪的是,如果我不

LOCAL_SHARED_LIBRARIES += libmyegl_impl 
Android.mk中的

,然后手机不会抛出libmyegl_jni.so而不是有效的ELF可执行错误......

1 个答案:

答案 0 :(得分:0)

我知道这是一个老问题,但如果有其他人遇到此问题,可能会发生这种情况,因为您需要在实际库之前加载依赖的共享库。 在您的示例中,我认为它是libmyegl_impl:

System.loadLibrary("myegl_impl");
// ...
System.loadLibrary("myrenderer");