自分も少しやってみたので、わかる範囲でお答えします。
(誤りなどありましたら指摘いただけると嬉しいです)
・どのようにしてjavaで取得した数値配列をCに渡すのか
java側のint[]
という配列をCへ渡す際にはCの関数宣言を
... function_name(int* ia, int length)
... function_name(int ia[], int length)
(Cでは上の定義と同等です)
のようにしてやればよいと思います。Java側で用意するメソッド(com.sun.jna.Libraryを継承したinterface上のメソッド) は次のようになります。
... function_name(int[] ia, int length)
ちなみに、lengthは配列の長さを渡すための引数です。
・どのようにしてCで処理した文字列をjavaに返すのか
これは少々難しく感じます。最も簡単なのは、Cの関数の戻り値をconst char*
にし、Java側で用意するメソッドの戻り値の型をString
とする方法と思います。しかしながらこの素朴な方法には落とし穴があります。例えばスレッドセーフへの配慮です。Cの関数をスレッドセーフにする簡単な方法は、戻り値の領域を引数で与えるか(A)、または関数内でmallocする(B)ことですが、(A)はJNAをつっこんで学ぶ必要があり、(B)はJNAでは多分NGと思います(なぜならだれもfreeしてくれないから)。グローバル変数としてバッファーを用意し、バッファーの先頭アドレスを返すなら簡単ですが、そういう関数はスレッドセーフでないので、Java側で複数スレッドからの同時実行をガードする必要があります。
本件のベストな解を得るにはJNA本家の説明を熟読した方がよさそうです。
・JNAを利用する際,Cはgccでのコンパイルで共有ライブラリにすると利用ができる,という認識は正しいのか
・そもそもJNAを利用すればやりたいことは実現可能なのか
どちらもYESと思います。
ただ「文字列を返す」ところで述べたように、簡単に作れるケースとそうでないケースがありそうです。intなど単純な型のみならJNAのデフォルトの型マッピングのみで簡単に作れますが、ポインター、独自の型等々、少し複雑なインターフェースではJNAの仕様をよく調べてJava側にそれなりの配慮が必要です。
なお、JNAではLinux, Windows, Macintoshの代表的なシステム提供ライブラリー接続用のインターフェースクラスが最初から提供されているようで、これを使う分にはかなり簡単だと思います。cateyeさん回答コードはこの「既に存在するDLL内部の処理ルーチンをJavaから簡単に呼び出す」というJNAの便利さが最もよくあらわれている例ではないでしょうか。
余談:
ちなみに、自前でCによるDLLを始めて作るならこちらも苦労されるかも知れません。自分はEclipse CDTではちゃんと作れませんでした。Linuxでやると割合簡単につくれたのでWindowsは初心者にとってちょっと難易度高めかも知れません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/10/15 09:37
2017/10/15 10:00 編集
退会済みユーザー
2017/10/15 12:20