2017-05-12 8 views
1

私はクライアントとサーバーアプリケーションを持っています。クライアントはStringコマンドをサーバーに送信します。サーバーはJNAを使用して2つのDLLライブラリインターフェイスに関連する呼び出しを行います。当然のことですが、私はある時点で、もののJava側でポインタを使用する必要があります。シリアル化されていないため、Pointerオブジェクトをソケット接続経由で送信できません。これを回避するためには、Pointer.nativeValue(p)を使用してポインタのネイティブなlong値を取得し、そのlong値を接続経由で送信し、それを使用してクライアント側に新しいポインタを作成することを考えました。しかし、クライアント側のPointerオブジェクトは、サーバー側のPointerオブジェクトと同じネイティブな値を持ちますが、クライアント側のポインタは指し示されず、無効なメモリアクセスエラーが発生します。1つのJavaアプリケーションから別のJavaアプリケーションにJNAポインタを送信

私のクライアントアプリケーションでは、私はDLLを描画できるウィンドウを作成するためにJavaFXを使用しています。したがって、JavaFXウィンドウのHWNDを取得する必要があります。次に、JNAのHWNDオブジェクトのネイティブ値をサーバーに送信し、サーバーはその長いネイティブ値を使用してHWNDオブジェクトを再作成します。それは動作します。しかし、明らかにPointerと他の同様のJNAオブジェクトはそうではありません。私は、これらのPointerオブジェクトとHWNDオブジェクト(WinDefクラスの他のオブジェクト)との違いは、HWNDは実際にはネイティブな値であるということです。それはWindows自体から来ています。そうでなければネイティブとしてはかなり役に立たないでしょうウィンドウハンドル。しかし、私は、JNAポインタは現在実行中のJRE内にしか存在しないと思います。そのポインタ値を別のJRE(クライアントが動作しているところ)に転送することはできません。私は本当にこれについて100%確信していません。

私はCプログラミングの初心者だから、ポインタについてはあまり知られていませんが、JavaではCポインタがずっと少なくなっています。しかし、もし私がこれについて正しいアイデアを持っているかどうか、誰かに教えてください。さらに詳しく説明してください。私もIntByReferenceでこれを試してみました

// Server side (PointerTest class) 
public long getPtrVal() { 
    Pointer p = new Memory(100); 
    p.setString(0, "Test"); 
    long ptrVal = Pointer.nativeValue(p); 
    return ptrVal; // return value is processed in separate class 
} 

// Client side (MyClient sends String command, returns Object) 
public static void main(String[] args) { 
    MyClient c = new MyClient(); 
    long ret = (long) c.sendCommand("PointerTest"); 
    Pointer p = new Pointer(ret); 
    String pointerString = p.getString(0); 
    System.out.println(pointerString); 
} 

は、ここで私がやったことのほんの一例です。 Pointerオブジェクトのようにエラーは発生しませんでしたが、サーバ側で設定された値は1234でしたが、クライアント側で取得した値は0でした。

答えて

1

ポインタの値は、プロセスのアドレススペース。仮想メモリサブシステム(すべての汎用OS、特にWindowsを含む)を搭載したOSでは、そのようなアドレスは本質的にプロセス固有のものです。 1つのプロセスは、ポインタを介するかどうかにかかわらず、別のプロセスのメモリにアクセスできません。この種のメモリ保護は、意図的で非常に望ましい機能です。

一方、特定のOSがマシンスコープのリソースを提供する場合があります。 MS Windowsでは、ウィンドウはそのようなリソースであり、そのハンドルはすべてのプロセスに同じウィンドウを指定します。

関連する問題