Linux JNI实例及其JNI程序设计模板

简单实例说明待补充,实例源码可在此链接下载http://d.download.csdn.net/down/2389895/sanlinux

 

jniNative.cpp

 

#include "jniNative.h"
#include "mymain.h"

#include <stdio.h>

JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject arg, jstring instring)
{
    const char *str = (const char *)env->GetStringUTFChars(instring, JNI_FALSE);
    printf("HELLO,%s/n",str);
    env->ReleaseStringUTFChars(instring,str);
    return;
}

JNIEXPORT void JNICALL Java_HelloWorld_test(JNIEnv *env, jobject arg, jstring instring)
{
    const jbyte *str = (const jbyte *)env->GetStringUTFChars(instring, JNI_FALSE);
    test((const char *)str);
    env->ReleaseStringUTFChars(instring, (const char *)str);
    return;
}


jniNative.h

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

//javac HelloWorld.java
//javah HelloWorld
//Copy from HelloWorld.h

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    print
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_HelloWorld_print
  (JNIEnv *, jobject, jstring);

/*
 * Class:     HelloWorld
 * Method:    test
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_HelloWorld_test
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

 

mymain.cpp

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mymain.h"

void test(const char *str)
{
    char ch[50];
    int len = 0;
   
    strcat(ch,"Hello ");
    strcat(ch,"JNI,");
    //strcat(ch,str);
    len = strlen(ch) + strlen("THIS ");
    char *chnew = (char *)malloc(len);
    sprintf(chnew,"THIS %s",ch);
   
    printf("len = %d/n",len);
    printf("str = %s/n",str);
    printf("ch = %s/n",ch);
    printf("chnew = %s/n",chnew);
   
    return;
}

 

mymain.h

 

#ifdef __cplusplus
extern "C" {
#endif

void test(const char *str);

#ifdef __cplusplus
}
#endif

 

HelloWorld.java

 

class HelloWorld
{
    public static void main(String[] args) {
        new HelloWorld().print("It is me");
        new HelloWorld().test("JUST TEST");
    }
   
    static {
        System.loadLibrary("HelloWorld");
    }
   
    public native void print(String instring);
    public native void test(String instring);
}

 

Makefile


all: jniNative.o mymain.o libHelloWorld.so.1.0 libHelloWorld.so

jniNative.o: jniNative.cpp
    g++ -I/usr/lib/jvm/java-1.6.0/include/ -I/usr/lib/jvm/java-1.6.0/include/linux/ -c $<
mymain.o: mymain.cpp
    g++ $< -c -o $@
libHelloWorld.so.1.0: jniNative.o mymain.o
    g++ -shared -Wl,-soname,libhello.so.1 -o $@ $^
libHelloWorld.so: libHelloWorld.so.1.0
    cp $< $@

#g++ -I/usr/lib/jvm/java-1.6.0/include/ -I/usr/lib/jvm/java-1.6.0/include/linux/ -shared -o libHelloWorld.so jniNative.cpp   

clean:
    rm -rf jniNative.o mymain.o libHelloWorld.so.1.0 libHelloWorld.so *.class

 

do.sh

 

#!/bin/bash
export LD_LIBRARY_PATH=`pwd` && /
javac HelloWorld.java && java HelloWorld

 

PinyinIME输入法JNI写法:

com_android_inputmethod_pinyin_PinyinDecoderService.cpp

 

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <cutils/log.h>
#include <jni.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "../include/pinyinime.h"
#include "../include/sync.h"
#include "../include/userdict.h"

#ifdef __cplusplus
extern "C" {
#endif

using namespace ime_pinyin;

#define RET_BUF_LEN 256

static char16 retbuf[RET_BUF_LEN];
static char16 (*predict_buf)[kMaxPredictSize + 1] = NULL;
static size_t predict_len;

static Sync sync_worker;

static struct file_descriptor_offsets_t
{
  jclass mClass;
  jfieldID mDescriptor;
} gFileDescriptorOffsets;

JNIEXPORT jboolean JNICALL nativeImOpenDecoder (JNIEnv* env, jclass jclazz,
                                               jbyteArray fn_sys_dict,
                                               jbyteArray fn_usr_dict) {
  jbyte *fsd = (*env).GetByteArrayElements(fn_sys_dict, 0);
  jbyte *fud = (*env).GetByteArrayElements(fn_usr_dict, 0);

  jboolean jret = JNI_FALSE;

  if (im_open_decoder((const char*)fsd, (const char*)fud))
    jret = JNI_TRUE;

  (*env).ReleaseByteArrayElements(fn_sys_dict, fsd, 0);
  (*env).ReleaseByteArrayElements(fn_usr_dict, fud, 0);

  return jret;
}

JNIEXPORT jboolean JNICALL nativeImOpenDecoderFd (JNIEnv* env, jclass jclazz,
                                                 jobject fd_sys_dict,
                                                 jlong startoffset,
                                                 jlong length,
                                                 jbyteArray fn_usr_dict) {
  jint fd = env->GetIntField(fd_sys_dict, gFileDescriptorOffsets.mDescriptor);
  jbyte *fud = (*env).GetByteArrayElements(fn_usr_dict, 0);

  jboolean jret = JNI_FALSE;

  int newfd = dup(fd);
  if (im_open_decoder_fd(newfd, startoffset, length, (const char*)fud))
    jret = JNI_TRUE;

  close(newfd);

  (*env).ReleaseByteArrayElements(fn_usr_dict, fud, 0);

  return jret;
}

JNIEXPORT void JNICALL nativeImSetMaxLens (JNIEnv* env, jclass jclazz,
                                          jint max_sps_len,
                                          jint max_hzs_len) {
  im_set_max_lens(static_cast<size_t>(max_sps_len),
                  static_cast<size_t>(max_hzs_len));
  return;
}

JNIEXPORT jboolean JNICALL nativeImCloseDecoder (JNIEnv* env, jclass jclazz) {
  im_close_decoder();
  return JNI_TRUE;
}

JNIEXPORT jint JNICALL nativeImSearch (JNIEnv* env, jclass jclazz,
                                      jbyteArray pybuf, jint pylen) {
  jbyte *array_body = (*env).GetByteArrayElements(pybuf, 0);

  jint jret = 0;
  if (NULL != array_body) {
    jret = im_search((const char*)array_body, pylen);
  }

  (*env).ReleaseByteArrayElements(pybuf, array_body, 0);

  return jret;
}

JNIEXPORT jint JNICALL nativeImDelSearch (JNIEnv* env, jclass jclazz, jint pos,
                                         jboolean is_pos_in_splid,
                                         jboolean clear_fixed_this_step) {
  return im_delsearch(pos, is_pos_in_splid, clear_fixed_this_step);
}

JNIEXPORT void JNICALL nativeImResetSearch (JNIEnv* env, jclass jclazz) {
  im_reset_search();
  return;
}

JNIEXPORT jint JNICALL nativeImAddLetter (JNIEnv *env, jclass clazz, jbyte ch) {
  return im_add_letter(ch);
}

JNIEXPORT jstring JNICALL nativeImGetPyStr (JNIEnv* env, jclass jclazz,
                                           jboolean decoded) {
  size_t py_len;
  const char *py = im_get_sps_str(&py_len);  // py_len gets decoded length
  assert(NULL != py);
  if (!decoded)
    py_len = strlen(py);

  const unsigned short *spl_start;
  size_t len;
  len = im_get_spl_start_pos(spl_start);

  size_t i;
  for (i = 0; i < py_len; i++)
    retbuf[i] = py[i];
  retbuf[i] = (char16)'/0';

  jstring retstr = (*env).NewString((unsigned short*)retbuf, i);
  return retstr;
}

JNIEXPORT jint JNICALL nativeImGetPyStrLen (JNIEnv* env, jclass jclazz,
                                           jboolean decoded) {
  size_t py_len;
  const char *py = im_get_sps_str(&py_len);  // py_len gets decoded length
  assert(NULL != py);
  if (!decoded)
    py_len = strlen(py);
  return py_len;
}

JNIEXPORT jintArray JNICALL nativeImGetSplStart (JNIEnv* env, jclass jclazz) {
  const unsigned short *spl_start;
  size_t len;

  // There will be len + 1 elements in the buffer when len > 0.
  len = im_get_spl_start_pos(spl_start);

  jintArray arr = (*env).NewIntArray(len + 2);
  jint *arr_body = (*env).GetIntArrayElements(arr, 0);
  assert(NULL != arr_body);
  arr_body[0] = len; // element 0 is used to store the length of buffer.
  for (size_t i = 0; i <= len; i++)
    arr_body[i + 1] = spl_start[i];

  (*env).ReleaseIntArrayElements(arr, arr_body, 0);

  return arr;
}

JNIEXPORT jstring JNICALL nativeImGetChoice (JNIEnv *env, jclass clazz,
                                            jint candidateId) {
  jstring retstr;
  if(im_get_candidate(candidateId, retbuf, RET_BUF_LEN)) {
    retstr = (*env).NewString(retbuf, utf16_strlen(retbuf));
    return retstr;
  } else {
    retstr = (*env).NewString((unsigned short*)retbuf, 0);
    return retstr;
  }
}

JNIEXPORT jint JNICALL nativeImChoose (JNIEnv *env, jclass clazz,
                                      jint choice_id) {
  return im_choose(choice_id);
}

JNIEXPORT jint JNICALL nativeImCancelLastChoice (JNIEnv *env, jclass clazz) {
  return im_cancel_last_choice();
}

JNIEXPORT jint JNICALL nativeImGetFixedLen (JNIEnv *env, jclass clazz) {
  return im_get_fixed_len();
}

JNIEXPORT jboolean JNICALL nativeImCancelInput (JNIEnv *env, jclass clazz) {
  if (im_cancel_input())
    return JNI_TRUE;

  return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL nativeImFlushCache (JNIEnv *env, jclass clazz) {
  im_flush_cache();
  return JNI_TRUE;
}

JNIEXPORT jint JNICALL nativeImGetPredictsNum (JNIEnv *env, jclass clazz,
                                              jstring fixed_str) {
  char16 *fixed_ptr = (char16*)(*env).GetStringChars(fixed_str, false);
  size_t fixed_len = (size_t)(*env).GetStringLength(fixed_str);

  char16 fixed_buf[kMaxPredictSize + 1];

  if (fixed_len > kMaxPredictSize) {
    fixed_ptr += fixed_len - kMaxPredictSize;
    fixed_len = kMaxPredictSize;
  }
  utf16_strncpy(fixed_buf, fixed_ptr, fixed_len);
  fixed_buf[fixed_len] = (char16)'/0';

  predict_len = im_get_predicts(fixed_buf, predict_buf);

  (*env).ReleaseStringChars(fixed_str, fixed_ptr);

  return predict_len;
}

JNIEXPORT jstring JNICALL nativeImGetPredictItem (JNIEnv *env, jclass clazz,
                                                 jint predict_no) {
  jstring retstr;

  if (predict_no < 0 || (size_t)predict_no >= predict_len) {
    retstr = (*env).NewString((unsigned short*)predict_buf[0], 0);
  } else {
    retstr = (*env).NewString((unsigned short*)predict_buf[predict_no],
                              utf16_strlen(predict_buf[predict_no]));
  }
  return retstr;
}

JNIEXPORT jboolean JNICALL nativeSyncBegin (JNIEnv *env, jclass clazz,
                                           jbyteArray dict_file) {
  jbyte *file_name = (*env).GetByteArrayElements(dict_file, 0);

  jboolean jret = JNI_FALSE;
  if (true == sync_worker.begin((const char *)file_name))
    jret = JNI_TRUE;

  (*env).ReleaseByteArrayElements(dict_file, file_name, 0);

  return jret;
}

JNIEXPORT jboolean JNICALL nativeSyncFinish (JNIEnv *env, jclass clazz) {
  sync_worker.finish();
  return JNI_TRUE;
}

JNIEXPORT jint JNICALL nativeSyncGetCapacity (JNIEnv *env, jclass clazz) {
  return sync_worker.get_capacity();
}

JNIEXPORT jint JNICALL nativeSyncPutLemmas(JNIEnv *env, jclass clazz,
                                           jstring tomerge) {

  char16 *ptr = (char16*)(*env).GetStringChars(tomerge, NULL);
  int len = (size_t)(*env).GetStringLength(tomerge);

  int added = sync_worker.put_lemmas(ptr, len);

  (*env).ReleaseStringChars(tomerge, ptr);

  return added;
}

JNIEXPORT jstring JNICALL nativeSyncGetLemmas (JNIEnv *env, jclass clazz) {

  int len = sync_worker.get_lemmas(retbuf, RET_BUF_LEN);
  if (len == 0)
    return NULL;
  jstring retstr;
  retstr = (*env).NewString((unsigned short*)retbuf, len);
  return retstr;
}

JNIEXPORT jint JNICALL nativeSyncGetLastCount (JNIEnv *env, jclass clazz) {
  return sync_worker.get_last_got_count();
}

JNIEXPORT jint JNICALL nativeSyncGetTotalCount(JNIEnv *env, jclass clazz) {
  return sync_worker.get_total_count();
}

JNIEXPORT jboolean JNICALL nativeSyncClearLastGot (JNIEnv *env, jclass clazz) {
  sync_worker.clear_last_got();
  return JNI_TRUE;
}

/**
 * Table of methods associated with a single class.
 */
static JNINativeMethod gMethods [] = {
    /* name, signature, funcPtr */
    /* ------Functions for Pinyin-to-hanzi decoding begin--------->> */
    { "nativeImOpenDecoder", "([B[B)Z",
            (void*) nativeImOpenDecoder },
    { "nativeImOpenDecoderFd", "(Ljava/io/FileDescriptor;JJ[B)Z",
            (void*) nativeImOpenDecoderFd },
    { "nativeImSetMaxLens", "(II)V",
            (void*) nativeImSetMaxLens },
    { "nativeImCloseDecoder", "()Z",
            (void*) nativeImCloseDecoder },
    { "nativeImSearch",  "([BI)I",
            (void*) nativeImSearch },
    { "nativeImDelSearch",  "(IZZ)I",
            (void*) nativeImDelSearch },
    { "nativeImResetSearch",  "()V",
            (void*) nativeImResetSearch },
    { "nativeImAddLetter", "(B)I",
            (void*) nativeImAddLetter },
    { "nativeImGetPyStr", "(Z)Ljava/lang/String;",
            (void*) nativeImGetPyStr },
    { "nativeImGetPyStrLen", "(Z)I",
            (void*) nativeImGetPyStrLen },
    { "nativeImGetSplStart", "()[I",
            (void*) nativeImGetSplStart },
    { "nativeImGetChoice", "(I)Ljava/lang/String;",
            (void*) nativeImGetChoice },
    { "nativeImChoose", "(I)I",
            (void*) nativeImChoose },
    { "nativeImCancelLastChoice", "()I",
            (void*) nativeImCancelLastChoice },
    { "nativeImGetFixedLen", "()I",
            (void*) nativeImGetFixedLen },
    { "nativeImGetPredictsNum", "(Ljava/lang/String;)I",
            (void*) nativeImGetPredictsNum },
    { "nativeImGetPredictItem", "(I)Ljava/lang/String;",
            (void*) nativeImGetPredictItem },
    { "nativeImCancelInput", "()Z",
            (void*) nativeImCancelInput },
    { "nativeImFlushCache", "()Z",
            (void*) nativeImFlushCache },
    /* <<----Functions for Pinyin-to-hanzi decoding end------------- */

    /* ------Functions for sync begin----------------------------->> */
    { "nativeSyncBegin", "([B)Z",
            (void*) nativeSyncBegin },
    { "nativeSyncFinish", "()Z",
            (void*) nativeSyncFinish },
    { "nativeSyncPutLemmas", "(Ljava/lang/String;)I",
            (void*) nativeSyncPutLemmas },
    { "nativeSyncGetLemmas", "()Ljava/lang/String;",
            (void*) nativeSyncGetLemmas },
    { "nativeSyncGetLastCount", "()I",
            (void*) nativeSyncGetLastCount },
    { "nativeSyncGetTotalCount", "()I",
            (void*) nativeSyncGetTotalCount },
    { "nativeSyncClearLastGot", "()Z",
            (void*) nativeSyncClearLastGot },
    { "nativeSyncGetCapacity", "()I",
            (void*) nativeSyncGetCapacity },
    /* <<----Functions for sync end--------------------------------- */
};


/*
 * Register several native methods for one class.
 */
static int registerNativeMethods (JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = (*env).FindClass(className);
    if (clazz == NULL) {
        return JNI_FALSE;
    }
    if ((*env).RegisterNatives (clazz, gMethods, numMethods) < 0) {
        return JNI_FALSE;
    }

    clazz = env->FindClass("java/io/FileDescriptor");
    LOG_FATAL_IF(clazz == NULL, "Unable to find Java class java.io.FileDescriptor");
    gFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    gFileDescriptorOffsets.mDescriptor = env->GetFieldID(clazz, "descriptor", "I");
    LOG_FATAL_IF(gFileDescriptorOffsets.mDescriptor == NULL,
                 "Unable to find descriptor field in java.io.FileDescriptor");

    return JNI_TRUE;
}

/*
 * Register native methods for all classes we know about.
 */
static int registerNatives (JNIEnv* env)
{
    if (!registerNativeMethods (env,
           "com/android/inputmethod/pinyin/PinyinDecoderService ",
            gMethods, sizeof(gMethods) / sizeof(gMethods[0])))
        return JNI_FALSE;

    return JNI_TRUE;
}

/*
 * Set some test stuff up.
 *
 * Returns the JNI version on success, -1 on failure.
 */
JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if ((*vm).GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        goto bail;
    }
    assert(env != NULL);

    if (!registerNatives(env) ) {
        goto bail;
    }

    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

bail:
    return result;
}

#ifdef __cplusplus
}
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值