- PR -

JNIについて

投稿者投稿内容
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-07 07:36
Java ラッパークラスのソースコードです。

コード:
// OtherSystem.java

// VbCom.OtherSystem COMのラッパークラス
class OtherSystem {

	protected int pComObject = 0;		// COMオブジェクトのポインタ

	static {
		// JNI DLL(VbComWrapper.dll)をロードする
		System.loadLibrary("VbComWrapper");
	}

	public OtherSystem() {
		// コンストラクタ内でCOMのインスタンス生成をしておく
		_create();
	}
	private native void _create();	// COMインスタンスの生成
	public native void dispose();	// COMインスタンスの破棄

	// COMのラッパーメソッド
	public native String getData();					// VbCom.OtherSystem.GetDataメソッド
	public native void sendData(String data);		// VbCom.OtherSystem.GetDataメソッド


	// COMラッパークラスの使い方
	public static void main(String[] args) {
		
		// インスタンス生成
		OtherSystem otherSystem = new OtherSystem();
		
		// 他システムからデータ取得する(VbCom.OtherSystem.GetDataメソッド呼び出し)
		String data = otherSystem.getData();
		System.out.println("data:" + data);
		
		// 他システムへデータを送信する(VbCom.OtherSystem.SendDataメソッド呼び出し)
		otherSystem.sendData("SHOHIN_CODE0002,みかん,¥50");
		
		
		// 用が済めば、disposeメソッドで破棄をすること
		otherSystem.dispose();
	}

}


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-07 07:38
VC++ JNIのソースコードです。

コード:
// JNI実装 (VbComWrapper.dll)

// 必要なヘッダファイルをインクルード
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include "OtherSystem.h"	// javahにより自動生成されたヘッダファイル

// COMタイプライブラリをインポート
#import "VbCom.dll"			// VB6のDLL
using namespace VbCom;

// DLLエントリポイント関数の定義
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
	switch (fdwReason) {
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
		// DLLロード時にCOMライブラリを初期化する
		::CoInitialize(NULL);
		break;

	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		// DLLアンロード時にCOMライブラリの後処理をする
		::CoUninitialize();
		break;
	}

    return TRUE;
}

// OtherSystem._createメソッドの実装
JNIEXPORT void JNICALL Java_OtherSystem__1create
  (JNIEnv* env, jobject obj)
{
	// pComObjectフィールドのフィールドID取得
	jclass cls = env->GetObjectClass(obj);
	jfieldID fieldID = env->GetFieldID(cls, "pComObject", "I"); 

	// VbCom.OtherSystemインスタンスを生成
	HRESULT hr;
	_OtherSystem* pOtherSystem = NULL;
	hr = ::CoCreateInstance(__uuidof(OtherSystem), NULL, CLSCTX_INPROC_SERVER, __uuidof(_OtherSystem), (void**)&pOtherSystem);

	if (SUCCEEDED(hr)) {	// 生成に成功
		// pComObjectにVbCom.OtherSystemインスタンスのポインタを格納
		env->SetIntField(obj, fieldID, (jint)pOtherSystem);
	}
	else {					// 生成に失敗
		env->SetIntField(obj, fieldID, (jint)NULL);
		// エラーを出力
		printf("CoCreateInstance failed!!\\n");
	}
}

// OtherSystem.disposeメソッドの実装
JNIEXPORT void JNICALL Java_OtherSystem_dispose
  (JNIEnv* env, jobject obj)
{
	// pComObjectフィールドのフィールドID取得
	jclass cls = env->GetObjectClass(obj);
	jfieldID fieldID = env->GetFieldID(cls, "pComObject", "I"); 

	// VbCom.OtherSystemインスタンスのポインタを取得
	_OtherSystem* pOtherSystem = (_OtherSystem*)env->GetIntField(obj, fieldID);

	if (pOtherSystem) {		// VbCom.OtherSystemインスタンスのポインタがNULLでないとき

		// VbCom.OtherSystemインスタンスを開放する
		pOtherSystem->Release();
		// pComObjectにNULLをセットする
		env->SetIntField(obj, fieldID, (jint)NULL);
	}
}

// OtherSystem.getDataメソッドの実装
JNIEXPORT jstring JNICALL Java_OtherSystem_getData
  (JNIEnv* env, jobject obj)
{
	// pComObjectフィールドのフィールドID取得
	jclass cls = env->GetObjectClass(obj);
	jfieldID fieldID = env->GetFieldID(cls, "pComObject", "I"); 

	// VbCom.OtherSystemインスタンスのポインタを取得
	_OtherSystem* pOtherSystem = (_OtherSystem*)env->GetIntField(obj, fieldID);

	bstr_t data;
	if (pOtherSystem) {
		// VbCom.OtherSystem.GetDataメソッドを呼び出す
		data = pOtherSystem->GetData();
	}

	// 結果を返す
	return env->NewString(data, data.length());
}

// OtherSystem.sendDataメソッドの実装
JNIEXPORT void JNICALL Java_OtherSystem_sendData
  (JNIEnv* env, jobject obj, jstring data)
{
	// pComObjectフィールドのフィールドID取得
	jclass cls = env->GetObjectClass(obj);
	jfieldID fieldID = env->GetFieldID(cls, "pComObject", "I"); 

	// VbCom.OtherSystemインスタンスのポインタを取得
	_OtherSystem* pOtherSystem = (_OtherSystem*)env->GetIntField(obj, fieldID);

	// 引数(文字列)をマーシャリングする
	bstr_t bstrData = env->GetStringChars(data, JNI_FALSE);
	if (pOtherSystem) {
		// VbCom.OtherSystem.SendDataメソッドを呼び出す。
		pOtherSystem->SendData(bstrData);
	}
}

Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-07 07:43
ソースコードは以上です。
#汚いコードでスイマセン

以下、具体的な作成方法・実行方法を書いておきます。

【VB DLLの作成】
 1.VB6を起動し、「ActiveX DLL」を新規作成します。
 2.プロジェクト名とクラス名に適切な名前をつけます。
    プロジェクト名:VbCom
    クラス名:OtherSystem
 3.クラスモジュールにソースコードをコピペします。
 4.ビルドしてVbCom.dllを生成します。
 5.regsvr32コマンドでDLLをCOMとして登録します。
    regsvr32 c:\\VbCom.dll
   #登録解除したい場合は次のようにします
    regsvr32 /u c:\\VbCom.dll

【Java ラッパークラスの作成】
 1.OtherSystem.javaファイルにソースコードをコピペします。
 2.コンパイルします。
    javac OtherSystem.java
 3.JNIヘッダファイルを生成します
    javah -jni OtherSystem

【VC++ JNIの作成】
 1.VC++6を起動します。
 2.「Win32 Dynamic-Link Library」を新規作成します。
    プロジェクト名:VbComWrapper
   ウィザードで「空のプロジェクト」を選択
 3.C++ソースコードを新規作成し VbComWrapper.cpp(ファイル名は任意)、ソースコードをコピペします。
 4.javahで自動生成されたヘッダファイル(OtherSystem.h)をプロジェクトフォルダにコピーします。
 5.VBでビルドしたDLL(VbCom.dll)をプロジェクトフォルダにコピーします。
 6.ビルドして、VbComWrapper.dllを生成します。

【動作確認】
 JNI DLL(VbComWrapper.dll)を適当な場所(パスの通ったところ)にコピーし
 OtherSystem.classを実行します。
  java OtherSystem


#なにか不明な点などがございましたら、ご質問ください。
#私はJava素人なので、Javaについては詳しくありませんが(~_~;)

ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2005-12-07 09:48
Tdnr_Symさん、おはようございます。
サンプルソースありがとうございます。
もしかして昨晩の遅い時間に作ってくださったのですか?
本当に感謝しております。
もう何と言っていいのか言葉がありません。
Tdnr_Symさんのおかげで希望の光が見えてきました。
VBやVCは少し触れたことがある程度なので
環境設定に時間がかかってしまうかもしれませんが、
これからVBとVC++6をインストールして動かしてみます。
うまく動きましたら報告いたします。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-12-07 11:21
引用:
VBやVCは少し触れたことがある程度なので


Tdnr_Sym さんには悪いけど、MMX さんの紹介している JCom を使ったほうがいいと思います。JCom を使ったほうが情報も多く扱いやすいですし、なにより JNI を意識しなくて良い(自分で C のコードを書く必要が一切ない)というメリットがあります。

ちなみに、JCom は、渡辺さんという日本の方が作成されたもので、日本語のドキュメント・サンプルがとても充実しています。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-07 12:46
引用:

未記入さんの書き込み (2005-12-07 11:21) より:
Tdnr_Sym さんには悪いけど、MMX さんの紹介している JCom を使ったほうがいいと思います。JCom を使ったほうが情報も多く扱いやすいですし、なにより JNI を意識しなくて良い(自分で C のコードを書く必要が一切ない)というメリットがあります。


いえ、全然悪くないですよ。仰るとおりですから。
私もどこまでサポートできるか分かりませんし、
ネット上のやり取りだけではきっと限界があると思います。
ヒロピンさんが、どの方法を選択されるか分かりませんが
VCに詳しくなかったり、ヒロピンさんのお近くにVCに詳しい人がいないのであれば、
あまりお勧めできる方法ではありませんね。

引用:

ちなみに、JCom は、渡辺さんという日本の方が作成されたもので、日本語のドキュメント・サンプルがとても充実しています。



私もJComをダウンロードして、ドキュメントを眺めていたら、
日本人の方が作成されてるんだなぁと気づきました。
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2005-12-07 13:22
私の会社にVCに詳しい人はいませんが、
Tdnr_Symさんに教えていただいた方法で
とりあえずやってみます。

私もJComをダウンロードしてみましたが、
私にはマニュアルだけ見てソースを作る力は
ないので・・・

午前中はインストールで終わってしまったので、
これからソースを書いて動かしてみます。

[ メッセージ編集済み 編集者: ヒロピン 編集日時 2005-12-07 13:23 ]
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2005-12-07 14:18
Tdnr_Symさん、教えてください。

VC++でコンパイルしたところ下記のようなエラーが出ました。

othersystem.h(2) : fatal error C1083: インクルード ファイルがオープンできません。
'jni.h': No such file or directory

何かパスが足りないのでしょうか?

スキルアップ/キャリアアップ(JOB@IT)