質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

1回答

10944閲覧

JNAを使用してJavaアプリケーションからC言語の関数の呼び出しができません。

dashi

総合スコア14

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2016/08/05 09:29

編集2016/08/08 01:50

matobaaさん

反応いただきありがとうございます。

ソース部分はコードタグで囲んでください。

初めて投稿したためにコードタグを入れるのを失念しておりました。
見難い記述をしてしまい誠に申し訳ございません。

gccにはなにを使っていますか?

minGWとなります。


前回、「やりたいこと」ととして記載した内容はよくよく考えると、
プロセスを跨いでいるため、プロセス間通信が必要となり、
単純にJavaアプリからの関数コールでは実現できないのではないかと思いました。

C言語で書いたhoge.exe(以下のプログラム)を実行中に、test.c内のsetTest()を
Javaアプリから呼び出し、main関数内で出力されるログを切り分けたいです。

よって、JavaアプリからJNAを使用してC言語の関数を呼び出す方法のみの質問に変更させてください。
お手数をおかけして申し訳ございません。

<質問事項見直し>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<開発環境>
Windows7 64bit
C言語のビルド環境:gcc (minGW)
Java言語のビルド・実行環境:Eclipse(Mars)
JDK 1.7.0_79(32bit)
※最初はjdk1.8.0_101(64bit)で実行していましたが、以下の記事を参考に32bitのJDKも構築した次第です。
http://d.hatena.ne.jp/nowokay/20120618

JNA:jna-4.2.2.jarをEclibseから読み込んでいます。

<前提>
以下の手順で"test.dll"を作成し、本dllをJavaアプリ内の「Native.loadLibrary」の引数に
指定しています。
・C:\MinGW>gcc -shared -o test.dll test.c

<やりたいこと>
JavaアプリからJNAを使用してC言語の関数(test.c内のtest_Printf())をコールしたい。

<質問事項>
Javaアプリ上に配置した「Port Closeボタン」を押下するとExceptionが発生します。(ソースコード内の(★))
eclipse上のエラーログを見ると、test.dllが32bitでビルドされていない旨の指摘に見えますが、
以下の記事を参考にtest.dllが32bitでビルドされていることは確認しています。
※test.dllのバイナリデータを確認すると、「0x504500004C01」となっていること
http://sow23.blog.fc2.com/blog-entry-19.html

また、Javaアプリケーションも以下の記事を参考に32bitのJDKでビルドしています。
http://www.searchman.info/java_eclipse/1070.html

その他の原因としてどのようなことが想定されますでしょうか?
継続して調査を行っておりますが、現状行き詰っている状態です。
些細なアドバイスでもいただけますと助かります。

<ソースコード>

C言語

1#include <stdio.h> 2void test_Printf(){ 3 printf("hello World:test_Printf()\n"); 4}

Java言語

1public class jw_test extends JFrame implements SerialPortEventListener{ 2 public interface CLibrary extends Library{ 3 CLibrary INSTANCE = (CLibrary)Native.loadLibrary("test.dll", CLibrary.class); 4 void test_Printf(); 5 } 6 public static void main(String[] args) { 7 EventQueue.invokeLater(new Runnable() { 8 public void run() { 9 try { 10 jw_test frame = new jw_test(); 11 frame.setVisible(true); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 } 16 }); 17 } 18 public jw_test() { 19 MainForm = this; 20 21 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 22 setBounds(100, 100, 450, 589); 23 contentPane = new JPanel(); 24 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 25 setContentPane(contentPane); 26 contentPane.setLayout(null); 27 28 btnPortClose = new JButton("Port Close"); 29 btnPortClose.addActionListener(new ActionListener() { 30 public void actionPerformed(ActionEvent e) { 31 textArea.setText("Port Close Clicked"); 32 if(commPort != null){ 33 commPort.close(); 34 } 35 CLibrary.INSTANCE.test_Printf(); ★アプリ上のCloseボタン押下でtest.c内の関数を呼び出したい 36 } 37 }); 38 } 39}

<エラーログ>
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: %1 は有効な Win32 アプリケーションではありません。

at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:263) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:403) at com.sun.jna.Library$Handler.<init>(Library.java:147) at com.sun.jna.Native.loadLibrary(Native.java:502) at com.sun.jna.Native.loadLibrary(Native.java:481) at jw_estorq$CLibrary.<clinit>(jw_estorq.java:65) at jw_estorq$3.actionPerformed(jw_estorq.java:151) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6535) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6300) at java.awt.Container.processEvent(Container.java:2236) at java.awt.Component.dispatchEventImpl(Component.java:4891) at java.awt.Container.dispatchEventImpl(Container.java:2294) at java.awt.Component.dispatchEvent(Component.java:4713) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466) at java.awt.Container.dispatchEventImpl(Container.java:2280) at java.awt.Window.dispatchEventImpl(Window.java:2750) at java.awt.Component.dispatchEvent(Component.java:4713) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) at java.awt.EventQueue.access$500(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.awt.EventQueue$3.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.awt.EventQueue$4.run(EventQueue.java:731) at java.awt.EventQueue$4.run(EventQueue.java:729) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

以上です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matobaa

2016/08/06 13:52

ソース部分はコードタグで囲んでください。 gccにはなにを使っていますか? cigwin, minGW, そのほか。
guest

回答1

0

ベストアンサー

"%1 は有効な Win32 アプリケーションではありません。"
このメッセージはOS側から帰ってきているようです。

検索してみた結果、以下のサイトがヒットしました。
microsoft support

このサイトによると、パスに問題があるとのことです。

一度、Native.loadLibraryのライブラリ名の部分を、
絶対パスにして動作させてみてはどうでしょうか、
この指摘が間違いであったとしても、問題の切り分けにはなると思います。

投稿2016/08/08 02:40

編集2016/08/08 02:42
abs123

総合スコア1280

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dashi

2016/08/08 07:29

>abs123さん コメントありがとうございます。 結論から言うと解決いたしました。 問題点としては2点ありましたので、 以下に過程を記載いたします。 1.絶対パスを指定した結果、以下のようにエラーが変わりました。 結果、以下のエラーから自作のライブラリのパスが通っていないようでした。 ・java.lang.UnsatisfiedLinkError: Unable to load library 'test.dll'.... よって、以下を参考にEclipse上で自作ライブラリのパス設定を実施しました。 http://sgrit.hatenablog.com/entry/2014/04/27/043015 2.Javaアプリを先に記載の通り32bitで動作させているつもりでしたが、 タスクマネージャーから確認した結果、64bitで動作しているようでした。 Eclipse上でJDKの切り替えは行っておりましたが、環境変数を変えていなかったため、 このような現象になってしまったのだと思います。 よって、jdk1.8.0_101(64bit)をアンインストールし、環境変数にJDK 1.7.0_79(32bit)を設定することでJavaアプリも32bitとして動作するようになりました。 上記問題点1,2の対応を行うことで、Eclipseのコンソールに""hello World:test_Printf()"が表示され、JavaアプリからC言語の関数がコールできていることが確認できました。 誠にありがとうございました。
abs123

2016/08/08 08:39 編集

私が想定していた状況とは違っていたようですが、 解決できたみたいでよかったです。 Eclipse上のJDKを切り替えたというのは、 もしかしたらEclipse自体の実行環境が変わっただけか、 Eclipseが扱えるJRE、JDKの種類が増えただけで、 プロジェクトの方の設定が変わっていない可能性があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問