phonemefeature中功能模块及 KNI 的编写方法

phonemefeature中功能模块及 KNI 的编写方法

1 目录结构... PAGEREF _Toc325476518 \h1

2 如何添加一个subsystem.. PAGEREF _Toc325476519 \h 2

3 如何编译到KVM中去... PAGEREF _Toc325476520 \h 5

4 如何编写KNI代码... PAGEREF _Toc325476521 \h 6

附录. PAGEREF _Toc325476522 \h7

 

 

 

1 目录结构

 

1.1  midp\src目录下每个文件夹都是一个subsystem,每个文件夹中有一个subsystem.gmk 作为该subsystem 的 makefile。

 

 

 1.2  Subsystem 文件夹内是各个lib,各子系统的 subsystem.gmk 都要包含本子系统需要的 lib

 phonemefeature中功能模块及 KNI 的编写方法_第1张图片

1.3  在相应 lib 目录下,lib.gmk作为本lib的makefile,上层subsystem.gmk需要include该lib.gmk;一般地有3个文件夹,classes、include、native (or reference),分别用于(也许还有i3test,用于java测试代码):

 

classes:  java代码,其中的java接口函数调用C语言实现的native方法;

Include:  native中用到的头文件;

Native:  C实现的native 代码。

 


 

 

2 如何添加一个subsystem

2.1  添加一个subsystem需要的文件一般如下:

src/subsystem.gmk

src/lib.gmk

src/native -- Thiscontains native implementation

src/classes --This contains your java implementation

src/include ---This contains native header files

 

2.2  一般步骤如下:

step 1: 添加子系统test

step 2: 编写subsystem.gmk

step 3: 添加库test_a

step 4: 在test_a下编写classes\native代码

step 5: 编写lib.gmk

 

 phonemefeature中功能模块及 KNI 的编写方法_第2张图片

 

2.3  subsystem.gmk 示例( 其中SUBSYSTEM_DIR = $(MIDP_DIR)/src )

 

######################################################################

# 2012-05-22 Written byFurtherChan

#

# Module's ComponentConfiguration file

######################################################################

# Add to global SUBSYSTEMSlist

 

SUBSYSTEM_TEST = test

 

SUBSYSTEMS +=$(SUBSYSTEM_TEST)

 

SUBSYSTEM_TEST_DIR =$(SUBSYSTEM_DIR)/test

 

#####################################################################

# test_a subsystem

# Description:

#####################################################################

 

include$(SUBSYSTEM_TEST_DIR)/test_a/lib.gmk

 

#####################################################################

# test_b subsystem

# Description:

#####################################################################

 

# include$(SUBSYSTEM_TEST_DIR)/test_b/lib.gmk

 

#####################################################################

# test_c subsystem

# Description:

#####################################################################

 

# include$(SUBSYSTEM_TEST_DIR)/test_c/lib.gmk

 

 

SUBSYSTEM_TEST_JAVA_FILES     += $(SUBSYSTEM_TEST_A_JAVA_FILES)

SUBSYSTEM_TEST_NATIVE_FILES += $(SUBSYSTEM_TEST_A_NATIVE_FILES)

#SUBSYSTEM_HIGHUI_EXTRA_INCLUDES  += $(SUBSYSTEM_ANNUNCIATOR_EXTRA_INCLUDES)

#SUBSYSTEM_HIGHUI_I3TEST_JAVA_FILES +=$(SUBSYSTEM_ANNUNCIATOR_I3TEST_JAVA_FILES)

 

 

 

2.4  lib.gmk 示例

 

######################################################################

# 2012-05-22 Written byFurtherChan

#

# TEST_A Library

######################################################################

 

# Name of the library

TEST_A_NAME = test_a

TEST_A_DIR =$(SUBSYSTEM_TEST_DIR)/$(TEST_A_NAME)

 

# Add to library set for thisbuild

LIB_SET += $(TEST_A_NAME)

 

# Export include files

#SUBSYSTEM_LCDLF_EXTRA_INCLUDES += -I$(TEST_A_DIR)/include

 

# Native files for thelibrary

SUBSYSTEM_TEST_NATIVE_FILES+= HelloWorld_kni.c

 

# Source code path for thelibrary

vpath % $(TEST_A_DIR)/native

 

 

# Java files for the library

#

SUBSYSTEM_TEST_JAVA_FILES += \

   $(TEST_A_DIR)/classes/first/second/third/HelloWorld.java

 

 

3 如何编译到KVM中去

3.1 把自己编写的native和java调用代码编译到KVM中去,需要修改一些makefile,也就是修改编译规则,把添加的代码加入到生成规则中去。在编译过程中可以看到如下信息:

 

=======================================

MIDPSubsystem and Module Configuration

=======================================

 

SUBSYSTEMS                  = configurationconfiguration properties_port example example verifier ams_folders ams_debugon_device_debug jams example core i18n highlevelui lowlevelui rms security derocsp gcf file http serial serial_port socket socket_notify ssocket udp pipepush events tool automation media

SUBSYSTEM_AMS_MODULES        = jams

SUBSYSTEM_EVENTS_MODULES     = master_mode

……

 

以上SUBSYSTEMS就是列出的被编译的subsystem。为了编译到SUBSYSTEMS中去,为此需要修改两个文件:

phoneme\midp\build\common\makefiles\Subsystems.gmk

phoneme\midp\build\common\makefiles\SubsystemDefs.gmk

其中前面的Subsystems.gmk 用于include 各个子系统的subsystem.gmk;

后面的SubsystemDefs.gmk 用于子系统lib源文件的添加,即添加lib.gmk中定义的几个变量:SUBSYSTEM_XXX_JAVA_FILESSUBSYSTEM_XXX_NATIVE_FILES等。

 

修改完毕后编译,可发现该subsystem已在SUBSYSTEMS中。

对于添加的native文件,在phoneme/output/midp/obj/arm/中可找到对应生成的obj文件;

对于添加的java文件,编译中有preverify .class过程,没有添加的情况下目前有621个。

 

3.2  Subsystems.gmk 添加示例

 

#####################################################################

# Test Subsystem

# 2012-05-22 Added byFurtherChan

#####################################################################

# 2012-05-22 Added byFurtherChan

include$(SUBSYSTEM_DIR)/test/$(SUBSYSTEM_MAKE_FILE)

# Added End

 

3.3  SubsystemDefs.gmk添加示例

 

#####################################################################

# Test Subsystem

# 2012-05-22 Added byFurtherChan

#####################################################################

# 2012-05-22 Added byFurtherChan

$(MIDP_CLASSES_ZIP)::$(SUBSYSTEM_TEST_JAVA_FILES)

    $(appendjavafiles)

 

JTWI_I3TEST_JAVA_FILES   += $(SUBSYSTEM_TEST_I3TEST_JAVA_FILES)

JTWI_NATIVE_FILES +=$(SUBSYSTEM_TEST_NATIVE_FILES)

# Added End

 

 

4 如何编写KNI代码

4.1 可用数据类型、参数传递方法、值返回方法等参考kni.h

 

4.2  C代码native函数命名遵循:Java_pkname1_pkname2_pkname3_classname_methodname(),

如:Java_first_second_third_HelloWorld_sayHello(),则对应的java实现函数在

classes\first\second\third\HelloWorld.java:public native void sayHello();

 

4.3 示例

 

midp\src\test\test_a\native\HelloWorld_kni.c:

 

#include <kni.h>

#include <stdio.h>

 

KNIEXPORT KNI_RETURNTYPE_VOIDJava_first_second_third_HelloWorld_sayHello()

{

         printf("KNITesting\n");

         KNI_ReturnVoid();

}

 

midp\src\test\test_a\classes\first\second\third\HelloWorld.java:

 

package first.second.third;

import java.lang.*;

 

public class HelloWorld

{

   public native void sayHello();

}

 

.附录

/**

 *KNI is an implementation-level native function interface

 *for CLDC-category VMs.  KNI is intendedto be significantly

 *more lightweight than JNI, so we have made some compromises:

 *

 * -Compile-time interface with static linking.

 * -Source-level (no binary level) compatibility.

 * -No argument marshalling. All native functions have

 *  signature void(*)(). Arguments are read explicitly,

 *   andreturn values are set explicitly.

 * -No invocation API (cannot call Java from native code).

 * -No class definition support.

 * -Limited object allocation support (strings only).

 * -Limited array region access for arrays of a primitive type.

 * -No monitorenter/monitorexit support.

 * -Limited error handling and exception support.

 *   KNIfunctions do not throw exceptions, but return error

 *  values/null instead, or go fatal for severe errors.

 * -Exceptions can be thrown explicitly, but no direct

 *  exception manipulation is supported.

 */

 

 

 

======================================================

 

KNI返回类型:cldc\src\vm\share\natives\kni.h

 

#define KNI_RETURNTYPE_VOID    void

#define KNI_RETURNTYPE_BOOLEAN jint

#define KNI_RETURNTYPE_BYTE    jint

#define KNI_RETURNTYPE_CHAR    jint

#define KNI_RETURNTYPE_SHORT   jint

#define KNI_RETURNTYPE_INT     jint

#define KNI_RETURNTYPE_FLOAT   JVM_SOFTFP_LINKAGE jfloat

#define KNI_RETURNTYPE_LONG    jlong

#define KNI_RETURNTYPE_DOUBLE  JVM_SOFTFP_LINKAGE jdouble

#define KNI_RETURNTYPE_OBJECT  jobject


你可能感兴趣的:(phonemefeature中功能模块及 KNI 的编写方法)