Android NDK JNI C++ <4> 文件结构分析和组织

这一篇文章主要熟悉NDK开发的jni文件目录结构分析和组织,当然开发一个小的小项目,当然不需要太注重文件结构结构和如何组织好文件结构.

开始分析:

<1> : 首先新建一个Android项目:SwigSimpleMk,由于这里不介绍Android的java程序,也不是将Android app如何调用jni,所以只给出最终文件结构和android主程序代码.

package com.example.swigsimplemk;

import org.swig.simple.MathOperation;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

    static{
        System.loadLibrary("example");
    }
    
    private MathOperation maths;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        maths=new MathOperation(1);
        
        Toast.makeText(this, "maths 1+2 = "+maths.Add(1, 2), Toast.LENGTH_SHORT).show();
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
View Code

文件结构大致如下:

由于展开太多了,可能不是很完整,但是这个不是重点.因为我把头文件,源文件,swg脚本,提供基本信息的help全部单独分开了.

/header文件夹下的example.h:

#ifndef _EXAMPLE_DEMO_HEADER_H_
#define _EXAMPLE_DEMO_HEADER_H_

class mathe{
public:
    mathe(){
        ;
    }
    virtual ~mathe(){
        ;
    }
    virtual int Add(int,int)=0;
    virtual int Subl(int,int)=0;
    virtual double Dulp(double,double)=0;
    virtual double Cdux(double,double)=0;

};

class MathOperation : public mathe{
public :
    MathOperation(int x){
        ;
    }
    virtual int Add(int,int);
    virtual int Subl(int,int);
    virtual double Dulp(double,double);
    virtual double Cdux(double,double);

};

#endif

/src文件夹下的example.cpp:这个文件有两个地方有,一个是在这里,一个直接放在jni文件夹下,不过内容是一样的,只是做个测试而已.

#include"../header/example.h"

/*
MathOperation::MathOperation() {
    cout << "MathOperation Init..." << endl;
}

MathOperation::~MathOperation() {
    cout << "MathOperation Release..." << endl;
}
*/

int MathOperation::Add(int x, int y) {
    return x + y;
}

int MathOperation::Subl(int x, int y) {
    return x > y ? (x - y) : (y - x);
}

double MathOperation::Dulp(double x, double y) {
    return x * y;
}

double MathOperation::Cdux(double x, double y) {
    return y == 0 ? 0 : (x / y);
}
View Code

/swig文件夹下的example.i

%module example
%{
#include "header/example.h"
%}
%include "../header/example.h"

第一个include将会直接加载到等下生成的example_wrap.cpp文件中,所以这个地方路径一定要正确,由于等下example_wrap.cpp路径是设置在jni文件夹下,所以example.h相对jni的目录应该是header/example.h才是正确的.

/help文件夹下的help.txt文件是运行example.i的命令行:

swig -c++ -java -package org.swig.simple -outdir ../../src/org/swig/simple -o ../example_wrap.cpp example.i

 

<3> : 准备上面的,现在主要介绍Android.mk的文件写法和路径:

如果要在jni文件夹下添加一个Android.mk,并且不打算在其他地方设置子目录下新建Android.mk,那么需要这样写:

#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := example
LOCAL_SRC_FILES := example_wrap.cpp src/example.cpp
LOCAL_CFLAGS    :=-frtti
$(warning $(LOCAL_PATH))
#include $(BUILD_SHARED_LIBRARY)

这里面要注意LOCAL_SRC_FILES := 后面的example.cpp文件路径设置法,这个路径是相对jni下的路径,准确的说是相对当前Android.mk文件的路径,而src是jni下文件夹,而Android.mk和jni文件是同级的,所以写法就是 : src/example.cpp.

这里面还需要注意一个地方,Android.mk也是可以打印调试信息:

语法:

$(warning $(~))或者$(error $(~))

这个里面打印LOCAL_PATH路径信息,实际就是jni的路径.

<4> : 这里面不在介绍shell脚本了,虽然我写了执行上面的,就可以生成了.so文件了.

 

<5> : 但是一个项目往往很大,分了很多一个子目录,那么都写在一个Android.mk,那将会多么的庞大,简直就是坑爹的难维护,所以经常会各个src下都会新建一个Android.mk

比如,我就在上面项目的src文件夹下新建一个Android.mk,但是jni下的还需要吗?需要,jni的Android.mk作为总入口,运行还是从Android.mk开始,然后通过这个总入口一次进入子目录下的各个Android.mk.

我这里总入口Android.mk :

#
LOCAL_PATH := $(call my-dir)
#LOCAL_PATH := $(call all-subdir-makefile)

include $(CLEAR_VARS)

#LOCAL_MODULE := example
#LOCAL_SRC_FILES := example_wrap.cpp src/example.cpp
#LOCAL_CFLAGS    :=-frtti
$(warning $(LOCAL_PATH))
#include $(BUILD_SHARED_LIBRARY)

include $(call all-makefiles-under,$(LOCAL_PATH))

上面的内容要用#注释掉,不要和子目录下的Android.mk功能重复.

 

然后再src文件夹下新建一个Android.mk:

#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := example
LOCAL_SRC_FILES := ../example_wrap.cpp ../example.cpp
#LOCAL_SRC_FILES := example.cpp
LOCAL_CFLAGS    :=-frtti

$(warning $(LOCAL_PATH))

include $(BUILD_SHARED_LIBRARY)

 

<6> : 然后在jni中同样输入ndk-build,得到同样的效果.

 

今天晚上太晚了,其他的明天再看看....

 

 

 

 

 

 

 

 

 

 

posted @ 2014-04-21 01:40  MMLoveMeMM  阅读(391)  评论(0)    收藏  举报