[NDK] JNI 中编译两个库文件。

来源:互联网 发布:哪类商品淘宝禁止出售 编辑:程序博客网 时间:2024/05/23 15:45

在NDK的例子中有这个例子,先编译出一个静态库,再编译出动态库并引用之前的静态库。其他部分一样,在jni目录下,


1. 之前一直定义不了GLfloat 数组,现在发现,因为MyRendererNative.h头文件会被com_example_nativeegl_MyRenderer.h文件引用。所以在其中定义数组会有问题。数组应该直接在MyRendererNative.cpp中声明定义。

如果头文件不被引用的话,直接在.h文件中声明就可以。

Hello.h#include <iostream>using namespace std;class Hello {int test[] = {1,2,3,4};  //Its ok because Hello.h没被引用};


The Android.mk file content:

#Description:makefile of Helloworld  LOCAL_PATH := $(call my-dir)#=======================include $(CLEAR_VARS)LOCAL_CFLAGS    := -WallLOCAL_MODULE    := libmyegl_implLOCAL_CPP_EXTENSION := .cpp#local_ldlibs is used for system libs and does not need dependencyLOCAL_LDLIBS += -llog -lGLESv1_CMLOCAL_SHARED_LIBRARIES += libcutils libutilsLOCAL_C_INCLUDES := \$(LOCAL_PATH)/include LOCAL_SRC_FILES := \MyRendererNative.cppLOCAL_CFLAGS:= -DLOG_TAG=\"MyRender\"#include $(BUILD_SHARED_LIBRARY)include $(BUILD_STATIC_LIBRARY)#========================include $(CLEAR_VARS)LOCAL_CFLAGS    := -WallLOCAL_MODULE    := myegl_jniLOCAL_C_INCLUDES := \$(LOCAL_PATH)/include LOCAL_CPP_EXTENSION := .cppLOCAL_LDLIBS += -llog -lGLESv1_CM#LOCAL_SHARED_LIBRARIES += libmyegl_impl  LOCAL_STATIC_LIBRARIES := libmyegl_implLOCAL_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.h

#include <jni.h>#include <string.h>#include <android/log.h>#include <GLES/gl.h>#include <GLES/glext.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <MyRendererNative.h>extern "C" {#define  LOG_TAG    "libgl_jni"#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)#define  LOGD(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)MyRenderer* myRenderer;} //end of extern "C"

cpp file

#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) {myRenderer->renderFrame();}/* * Class:     com_example_nativeegl_MyRenderer * Method:    nativeSurfaceChanged * Signature: (II)V */void nativeSurfaceChanged(JNIEnv *env, jobject obj, jint width, jint height){myRenderer->resize(width, height);}/* * Class:     com_example_nativeegl_MyRenderer * Method:    nativeSurfaceCreated * Signature: ()V */ void nativeSurfaceCreated(JNIEnv *env, jobject obj) { myRenderer = new MyRenderer(); myRenderer->init(); }//----------------------------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 registerNativeMethodsjint 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"

MyRendererNative.h

#include <string.h>#include <GLES/gl.h>#include <GLES/gl.h>#include <GLES/glext.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <android/log.h>#define  LOG_TAG    "libgl_impl"#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)#define  LOGD(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)class MyRenderer {private:GLfloat rtri;  //三角形的旋转变量GLfloat rquad;  //四边形的旋转变量int testintprivate;   //non-static variable need to be initialised in constructor methodpublic:static const GLfloat PI = 3.1415f;static int testintpublic;public:MyRenderer();virtual ~MyRenderer();void printGLString(char* name, GLenum s);void init();void resize(int width, int height);void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);void renderFrame();};

cpp file

#include "MyRendererNative.h"MyRenderer::MyRenderer():testintprivate(0) {}MyRenderer::~MyRenderer() {}int testintpublic = 12;   //static variable initialisation.void MyRenderer::printGLString(char* name, GLenum s) {char *v = (char *) glGetString(s);LOGI("GL %s = %s", name, v);}void MyRenderer::init() {LOGD("init the renderer");rtri= 0;glShadeModel(GL_SMOOTH);glClearColor(0.0f,0.0f, 0.0f, 0.0f);            //set the background color to black when starts to glclearglClearDepthf(1.0f);                               //set clear depth buffer bit to 1 when starts to glclearglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);}void MyRenderer::resize(int width, int height) {LOGD("resize the renderer");glViewport(0,0, width, height);  //window sizeglMatrixMode(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 MyRenderer::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);}static GLfloat gColors[] = {        1.0f,0.0f,0.0f, 1.0f,        0.0f,1.0f,0.0f, 1.0f,        0.0f,0.0f,1.0f, 1.0f,        1.0f,0.0f,0.0f, 1.0f,        0.0f,0.0f,1.0f, 1.0f,        0.0f,1.0f,0.0f, 1.0f,        1.0f,0.0f,0.0f, 1.0f,        0.0f,1.0f,0.0f, 1.0f,        0.0f,0.0f,1.0f, 1.0f,        1.0f,0.0f,0.0f, 1.0f,        0.0f,0.0f,1.0f, 1.0f,        0.0f,1.0f,0.0f, 1.0f};
static GLfloat gVertices[]= {        0.0f, 1.0f, 0.0f,        -1.0f,-1.0f, 1.0f,        1.0f,-1.0f, 1.0f,        0.0f, 1.0f, 0.0f,        1.0f,-1.0f, 1.0f,        1.0f,-1.0f, -1.0f,        0.0f, 1.0f, 0.0f,        1.0f,-1.0f, -1.0f,        -1.0f,-1.0f, -1.0f,         0.0f, 1.0f, 0.0f,        -1.0f,-1.0f,-1.0f,        -1.0f,-1.0f, 1.0f};void MyRenderer::renderFrame() {LOGD("renderFrame the renderer");// starts to clear the color buffer and depth buffer with the value set in glclearcolor and glcleardepthfglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();                              // 重置模型观察矩阵glTranslatef(0.0f,0.0f, -6.0f);             // 移入屏幕 6.0glRotatef(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();              //force the OpenGL commands set above to execute//force the OpenGL commands set above to execute. It will block the thread until above commands executed and returned.//glFinish();}