2009年6月6日 星期六

Java Native Interface 實做 傳java 函數

以下是我參考 的文章
hello world的話就參考下面的文章就好,這裡我是自己在寫出另一個範例
教學
http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=3997


Thinking in Java, 2nd edition, Revision 9

參數教學

http://dev.kanngard.net/Permalinks/ID_20050509144235.html

實作環境
ms XP

前置環境
  • 確定 java 有無安裝
關於這點可以參考java world "swanky "兄的文章
  • 確定 設定好 java path
  • 安裝 vc 環境
java lib 移到vc 的 lib

vc lib 位置
ex.
vs 2008 C:\Program Files\Microsoft Visual Studio 9.0\VC\lib
vc 6 C:\Program Files\Microsoft Visual Studio\VC98\Include

java 位置
C:\Program Files\Java\jdk1.6.0_11\lib jdk1.6.0_11 隨版本不同

步驟
1. 建立java file
2. 編譯出class 檔 ex. javac classname .java
3. 編譯出head 檔 給c, c++ 使用 ex javah -jni classname
4. 建立vc 專案 for dll
5. 複製 head 檔到vc 專案
6. 建立dll


建立java file
//-----------------------------------------------------------------------
// UseObjects.java
//-----------------------------------------------------------------------

class javaAddClass {
private int c;
public void setc(int varc){ this.c=varc;}
public int getc(){return this.c;}
public void add(int a, int b) { this.c = a+b; }
}

public class jniDemo {

// 宣告要傳給dll用的obj
private native void addObject(javaAddClass obj);

static {
// 讀取dll名稱
System.loadLibrary("jniDemo");
// Linux hack, if you can't get your library // path set in your environment: // System.load( //"/home/bruce/tij2/appendixb/UseObjImpl.so");
}


// 主程式
public static void main(String[] args) {

// 宣告新的物件
jniDemo app = new jniDemo();
javaAddClass jAddObj = new javaAddClass();

// 設定參數
jAddObj.setc(2);

// 呼叫dll
app.addObject(jAddObj);

// 測試有無執行dll,顯示變更後的值
System.out.println("Java: " + jAddObj.getc());
}
}


編譯出class 檔
javac UseObjects .
java

編譯出head 檔
javah -jni UseObjects

建立vc 專案 for dll, 並複製 head 檔到vc 專案
建立方式有很多文章 搜尋 vc dll 就很多了
以下轉貼兩篇
http://genewince.blogspot.com/2008/03/visual-c-dll-gene.html
http://www.functionx.com/visualc/libraries/staticdll.htm

附上DEMO 的 head檔和c檔

head 檔不用改,由java產生的複製
//-----------------------------------------------------------------------
// jniDemo.h
//-----------------------------------------------------------------------
* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class jniDemo */

#ifndef _Included_jniDemo
#define _Included_jniDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jniDemo
* Method: addObject
* Signature: (LjavaAddClass;)V
*/
JNIEXPORT void JNICALL Java_jniDemo_addObject
(JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif




//-----------------------------------------------------------------------

// jniDemo.cpp

//-----------------------------------------------------------------------

//: appendixb:UseObjImpl.cpp //# Tested with VC++ & BC++. Include path must //# be adjusted to find the JNI headers. See //# the makefile for this chapter (in the //# downloadable source code) for an example.

// jniDemo.cpp : Defines the exported functions for the DLL application. //

#include "stdafx.h"
#include "jniDemo.h"

extern "C" JNIEXPORT void JNICALL Java_jniDemo_addObject
(JNIEnv * env, jobject, jobject obj) {

// get class and name jAddClass
jclass jAddClass = env->GetObjectClass(obj);

// get function [ GetFieldID(class name, function name, type) ]
// java code : private int c

jfieldID jobjC = env->GetFieldID(
jAddClass, "c", "I");

// get function [ GetFieldID(class name, function name, type) ]
// java code : public void setc(int varc){ this.c=varc;}

jmethodID jobjSetc = env->GetMethodID(
jAddClass, "setc", "(I)V");

// get function [ GetFieldID(class name, function name, type) ]
// java code : public int getc(){return this.c;}

jmethodID jobjGetc = env->GetMethodID(
jAddClass, "getc", "()I");

// get function [ GetFieldID(class name, function name, type) ]
// java code : public void add(int a, int b) { this.c = a+b; }

jmethodID jobjAddc = env->GetMethodID(
jAddClass, "add", "(II)V");

// get value
int value = env->GetIntField(obj, jobjC);
printf("the C is : %d\n", value);

// call set function
env->CallVoidMethod(obj, jobjSetc, 5);
// call get function
int value2 = (int) env->CallObjectMethod(obj, jobjGetc);
printf("after set the C is : %d\n", value2);

// call add function
env->CallVoidMethod(obj, jobjAddc, 5, 6);
// call get function
int value3 = (int) env->CallObjectMethod(obj, jobjGetc);
printf("after add the C is : %d\n", value3);
}

建立dll
build 後,將dll移到java檔的位置,在執行
java UseObjects
即可
結果如下


沒有留言: