• 締切済み

JNIについて

JNI入門者なのですが、 少しJNIをやってみて、自分の中で発生した疑問について聞きたいです。 知りたいのが、 JNIはC/C++の利用で、FieldID、MethodID等で、ポインタ的なアプローチをしていますが、 高速である事意外に、javaのリフレクションと何が違うのか?という事です。 結局FindClassも、インスタンス化されていなければ、*env->NewObject(env,~とやって、 インスタンス化してあげないと、もし呼び出し元で参照されないところでnewされていたとしても、 そのクラスのインスタンスのインスタンスメソッドは呼べない、という事でいいのか? というところです。 WEB上で調べていると、情報が少なく、中にはあたかも、パッケージ名がわかれば、自由にVM内のインスタンスにアクセスできるような記載もあるので、よくわかりません。

  • Java
  • 回答数1
  • ありがとう数0

みんなの回答

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

> インスタンス化してあげないと、(略)そのクラスのインスタンスのインスタンスメソッドは呼べない、という事でいいのか? そのとおりです。

関連するQ&A

  • JNIについて

    JNIを使ったJavaコードの実行ができず困っています. 【Javaのコード】 public class HelloWorldJNI { static { System.loadLibrary("HelloWorldJNI"); } public native void sayHelloWorld(); public static void main(String[] args) { HelloWorldJNI hello = new HelloWorldJNI(); System.out.println("テスト"); hello.sayHelloWorld(); } } 【Cのコード】 #include "HelloWorldJNI.h" int main(int argc, char * argv[]) { return 0; } JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHelloWorld (JNIEnv *env, jobject obj ) { printf("Hello JNI World\n"); return; } 【Cのコンパイラ】 Microsoft Platform SDK for Windows Server 2003で, WindowsXP x64 Buid Environmentを使って,↓のようなバッチファイルを 実行しています. (OSは,WindowsXPのx64edition SP2です.) コンパイル・リンク中にエラーは出ません. 【ビルド】 echo off set JNI="C:\Program Files\Java\jdk1.6.0_07\include" set JNI1=%JNI%\win32 set OUTPUTDIR=. cl /nologo /c /I%JNI% /I%JNI1% /I. /LD /Zi /Od HelloWorldJNI.c LINK /nologo /NODEFAULTLIB /OPT:NOREF /out:HelloWorldJNI.dll HelloWorldJNI.obj bufferoverflowu.lib oldnames.lib kernel32.lib user32.lib netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib libcmtd.lib 【実行結果】 ↓こんなエラーになります. C:\WORK\>"C:\Program Files\Java\jre1.6.0_07\bin\java.ex e" HelloWorldJNI テスト # # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000001c0e8, pid=3864, t id=2528 # # Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0-b23 mixed mode windows-amd64) # Problematic frame: # C 0x000000000001c0e8 # # An error report file with more information is saved as: # C:\work\hs_err_pid3864.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. # 【質問】 原因となっていることや確認すべきことをご指摘頂ける方, いらっしゃいませんでしょうか.

    • ベストアンサー
    • Java
  • JNIを使用して、JAVAのメソッド実行結果の取得

    JNIを使用して、VC6からJAVA(アプリケーション)のメソッドを起動して結果を構造体(複数件数)で受け取る事は可能ですか。 JAVAからデータの取得を方法について教えて下さい。

    • ベストアンサー
    • Java
  • JNI 戻り値の渡し方について

    javaからCのdllを呼出すJNIを作っています。 やりたい事は ・C側で実行した結果がchar[256]に設定され、戻り値としてjava側に渡される。 ・java側でその中身を編集する ですが、java側で例外が発生します。 jcharArrayと言う型に入れさえすれば良いと思ってたのですが・・・ char[]をjava側で見る&編集する方法をどなたかご教授ください・・・。 よろしくお願いします。 ----------jnitest.dll---------- #include "stdafx.h" #include "../../JNI_test.h" #include <Windows.h> #include <stdio.h> #ifdef _MANAGED #pragma managed(push, off) #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif JNIEXPORT jcharArray JNICALL Java_JNI_1test_getScreenData(JNIEnv *env, jobject obj){ LONG ret; LONG id; char buff[256]; LPVOID lpvoid; DWORD len = 0; memset(buff,0x00,sizeof(buff)); lpvoid = buff; len = sizeof(buff); ~ここでbuffに値を設定する~ jcharArray result = (jcharArray)buff; return result; } ----------JNI_test.java---------- public class JNI_test { public native char[] getScreenData(); static{ System.loadLibrary("jnitest"); } public static void main(String[] args) { JNI_test jniObj = new JNI_test(); char[] kekka = jniObj.getScreenData(); System.out.println("出力内容:"+kekka);←ここで例外発生。 } }

  • privateのメソッドをリフレクションで呼び出す方法

    privateのメソッドをリフレクションで呼び出す方法 private のメソッドをリフレクションで呼び出す方法 privateのメソッドもリフレクションというもので呼び出せると聞きましたが、やり方がよく分かりません。 aaaやbbbクラスのインスタンスを生成したいのですが、privateやpackage privateのため、そのままだとインスタンスが生成できません。 forNameメソッドやnewInstanceメソッドでどうにかできないかと試してみたのですが、イリーガル例外が発生してしまいます。 何かよい方法がないでしょうか? aaa, bbbのクラスを継承してモックを作成する方法もあるのですが、今回はそういった方法ではなく、privateやpackage privateメソッド(特にコンストラクタ)を外部から呼び出す方法がよいです。 public aaa { private aaa() { } private func() { } } public bbb { aaa() { } private func() { } }

    • ベストアンサー
    • Java
  • VC++/MFCでリフレクション

    Javaでは、ObjectのgetClass()でClassクラスの インスタンスが取れ、実行時に指定した、メソッド名や、引数で、動的にメソッドを呼びだすようなリフレクション機能が使用できます。 同様のことをC#でも実装したことがあります。 VC++/MFCにて、このようなリフレクションをやるやり方を教えてください。 C++の標準あるいわ、MFCの機能など、どちらでもよいです。 メタクラス型のようなものを実行時に取得して、リフレクションする方法だと思います。 質問の内容はVC++.NETやVC++/CLIではないです。そちらのほうでのやり方は既に発見しました。

  • JavaからJNIを使わず既存DLLを呼び出す

    現在、GeneXusというジェネレータで出力されたJavaコードを、GeneXusが使用しているフレームワークに依存しない形で解体する作業を行っております。 作業を進めていくうちに、こちらのシステムの内部にwin32DLLを呼び出している箇所があることに気づきました。 DLLの内部の処理がかなり重要な処理なのですが、現状どうにも手を出せない状態です。 JNIを使用してソースからDLLをコンパイルしなおせばUnsatisfiedLinkErrorを回避できることが分かったのですが、DLLのソースがないのでJNIでヘッダ情報などを生成することができない状況です。 ちなみに、DLLはとあるpackageからコールされており、そのpackageからなら問題なくコールできるようです。しかし私が新たに作成したコードから呼び出すと、やはりUnsatisfiedLinkErrorで「nativeメソッドが見つかりません」と言われます。 どうにか、既存のDLLをJavaから呼び出す方法はないでしょうか? もしくは、DLLの内部の処理を解析する方法はないでしょうか。 完全に行き詰っておりますので、何か案があればよろしくお願いいたします。

  • JNIの文字列長

    JAVAからJNIを使用し、Cを起動しているのですが、 10000バイト以上の文字列をJAVAに返却しようとすると10000バイトより先が文字化けしてしまいます。 Cから直接起動した場合は10000バイト以上でも処理できます。 JAVAのインターフェースは以下のようになっています。 lRet = analyzeKBN( lCountin, sWORDin, lCountout,); lCountin : int型 入力文字数 sWORDin :String型 入力文字列 lCountout : int型 出力文字数 sWORDout : String型 出力文字列 Cの中を見渡しても10000文字の制限はありまません。 cの作業領域はlCountin を元にmallocしています。 出力文字列が10000バイト以上になるときっちり10000バイト以上が文字化けして帰ってくるのですが、JNIの制限等あるのでしょうか? 宜しくお願いします。

  • C#のdelegateをC++とjavaで?

    C#のデリゲードを javaとC++でできないでしょうか。 ただし、質問内容を勘違いされそうなので、求めている内容と、 求めていない内容を、詳しく 書きますと。 インタフェース委譲を使った例は、求めていません。 あらかじめ、委譲先に静的に仕組みを 作っておかなく手も、C#のデリゲードのように、シグニチァが同じなら 委譲先をはめ込めれるのが欲しいです。 単なる関数ポインタの例は、求めて いません。 C#でdelegate型を引数にとる ところに、あるインスタンスの メソッドを渡すと。 どのインスタンスのどのメソッドかまで、 認識して、コールバックできます。 関数ポインタでは、これができない。 STLの関数オブジェクトとか、古い感じの情報にヒントがあるか。調べてみましたが。よくわかりませんでした。 結局、この関数オブジェクトは、僕が求めているモノとは、違うような気がします。 よくわかりませんが。 欲しいのは、どのインスタンスのどのメソッドかまでを特定して、 記憶できる型をどうやって javaや、C++で実装できるか。 それをインタフェース委譲のように、 委譲先にあらかじめ、仕込んでおくことなしに。 ただ、メソッドのシグニチァが同じであるだけで、どのインスタンスのどのメソッドかまでを特定して記憶できる C#のデリゲードのような型を。 特殊なコンポーネントを利用せず。 標準的な言語構文のみをつかって、 どのようにしたら、 javaや、C++で、実装できるか? です。 詳しい方が、いらっしゃいましたら、 教えてください。

  • JavaとObjective-c間でJNIエラー

    JavaとObjective-c間でJNIを使用してGUIのアプリケーション連携を行いたいのですが エラーになってしまいます。 アプリケーションの起動をNSApplicationMain関数を使用してしようとしてるのですが、 JNIの関数では使用できないのでしょうか? 一部抜粋ですが、以下のように呼び出しています。 また、このように連携を行いたい場合、どのようにするべきでしょうか? ご教授ください。 JNIEXPORT void JNICALL Java_JniApp_start (JNIEnv *env, jobject this) { int argc = 0; char *argv[0]; NSApplicationMain(argc, (const char**)argv); } こちらをJava側で呼び出すとエラーとなります。 エラー内容は以下になります。 java[1646:1303] No Info.plist file in application bundle or no NSPrincipalClass in the Info.plist file, exiting

  • Java JNI C++ ログファイル生成される

    お世話になっております。 以前も何度か似たような質問をさせて頂いたのですが 未だ解決に至りませんので、再度質問させていただきます。 現在、JavaからC++の自作dllを呼び出し、 C++dllから外部開発dllの関数を使いハードウェアへコマンドを送信する。 というプログラムを開発しております。 そこで、プログラムを動かし、終了させると hs_pid...log が生成されます。 ログの内容(一部)↓ # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x1a212cd2, pid=4716, tid=4332 # # JRE version: 7.0_05-b05 # Java VM: Java HotSpot(TM) Client VM (23.1-b03 mixed mode windows-x86 ) # Problematic frame: # C [PCardRW32.dll+0x22cd2] crwSetLineControl+0x203b2 # # Failed to write core dump. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # C:\eclipse\workspace\ReWriteCard\hs_err_pid4716.log # # If you would like to submit a bug report, please visit: # http://bugreport.sun.com/bugreport/crash.jsp # どうやら、メモリアクセス違反を起こしているみたいなのですが logの内容は理解できません。 そこで、私が開発しましたプログラムを見て頂き、 BSTRの使い方がおかしいとのご指摘を受け、 しばらく調べていたのですが、どうにも改善できません。 C++のプログラム↓ JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; test = crwOpenPort(port, 9600 , "8" , "N"); BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); return jstr; } 上記のプログラムのBSTRの使い方が悪いのは、承知致しておりますが WideCharToMultiByte関数を使い、jstrへ変換し、 いかなる方法を試してもJava上で文字化けしますので とりあえず今は現状で使用しております。 そこで試しに、以下のようなプログラムにしてみました これだと、logファイルは生成されません。 JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; /* test = crwOpenPort(port, 9600 , "8" , "N"); BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); */ jstring jstr = env->NewStringUTF(""); return jstr; } しかし、以下のようにすると logファイルが生成されます。 JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; test = crwOpenPort(port, 9600 , "8" , "N"); /* BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); */ jstring jstr = env->NewStringUTF(""); return jstr; } だとすると、logとBSTRの問題は別物だと判断してもいいんでしょうか また、Java → 自作dll → 他社dll という構図に問題があるんでしょうか ささいなことでも構いません ご教授宜しくお願い致します。