質問編集履歴

1

やりたいことをJavaアプリからC言語の関数をコールする方法のみに変更させていただきました。\(理由は本文中に記載します\)

2016/08/08 01:50

投稿

dashi
dashi

スコア14

test CHANGED
File without changes
test CHANGED
@@ -1,226 +1,210 @@
1
+ >matobaaさん
2
+
3
+ 反応いただきありがとうございます。
4
+
5
+
6
+
7
+ >ソース部分はコードタグで囲んでください。
8
+
9
+ 初めて投稿したためにコードタグを入れるのを失念しておりました。
10
+
11
+ 見難い記述をしてしまい誠に申し訳ございません。
12
+
13
+
14
+
15
+ >gccにはなにを使っていますか?
16
+
17
+ minGWとなります。
18
+
19
+
20
+
21
+
22
+
23
+ 前回、「やりたいこと」ととして記載した内容はよくよく考えると、
24
+
25
+ プロセスを跨いでいるため、プロセス間通信が必要となり、
26
+
27
+ 単純にJavaアプリからの関数コールでは実現できないのではないかと思いました。
28
+
29
+ >C言語で書いたhoge.exe(以下のプログラム)を実行中に、test.c内のsetTest()を
30
+
31
+ >Javaアプリから呼び出し、main関数内で出力されるログを切り分けたいです。
32
+
33
+
34
+
35
+ よって、JavaアプリからJNAを使用してC言語の関数を呼び出す方法のみの質問に変更させてください。
36
+
37
+ お手数をおかけして申し訳ございません。
38
+
39
+
40
+
41
+ <質問事項見直し>
42
+
43
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
+
1
- <開発環境>
45
+ <開発環境>
2
-
46
+
3
- Windows7 64bit
47
+ Windows7 64bit
4
-
48
+
5
- C言語のビルド環境:gcc
49
+ C言語のビルド環境:gcc (minGW)
6
-
50
+
7
- Java言語のビルド・実行環境:Eclipse(Mars)
51
+ Java言語のビルド・実行環境:Eclipse(Mars)
8
-
52
+
9
- JDK 1.7.0_79(32bit)
53
+ JDK 1.7.0_79(32bit)
10
-
54
+
11
- ※最初はjdk1.8.0_101(64bit)で実行していましたが、以下の記事を参考に32bitのJDKも構築した次第です。
55
+ ※最初はjdk1.8.0_101(64bit)で実行していましたが、以下の記事を参考に32bitのJDKも構築した次第です。
12
-
56
+
13
- http://d.hatena.ne.jp/nowokay/20120618
57
+ http://d.hatena.ne.jp/nowokay/20120618
14
-
15
-
16
-
58
+
59
+
60
+
17
- JNA:jna-4.2.2.jarをEclibseから読み込んでいます。
61
+ JNA:jna-4.2.2.jarをEclibseから読み込んでいます。
18
62
 
19
63
 
20
64
 
21
65
  <前提>
22
66
 
23
- 以下の手順にて、hoge.exeを作成し、
67
+ 以下の手順で"test.dll"を作成し、本dllをJavaアプリ内の「Native.loadLibrary」の引数に
24
-
68
+
25
- コマンドプロンプトからhoge.exeを実行している状態です。
69
+ 指定していす。
26
-
27
-
28
-
29
- >gcc -c hello.c
70
+
30
-
31
- >gcc -c test.c
32
-
33
- >gcc -o hoge hello.o test.o
71
+ ・C:\MinGW>gcc -shared -o test.dll test.c
34
-
35
- >gcc -shared -o libtest.dll test.c ★Javaアプリから呼び出すために共有ライブラリを作成
36
-
37
-
38
-
39
- >hoge.exe ←★実行 getTest()で取得される値を監視
40
72
 
41
73
 
42
74
 
43
75
  <やりたいこと>
44
76
 
45
- C言語で書いたhoge.exe(以下のプログラム)を実行中に、test.c内のsetTest()を
77
+ JavaアプリからJNAを使用してC言語の関数(test.c内のtest_Printf())コールしたい。
78
+
79
+
80
+
46
-
81
+ <質問事項>
82
+
83
+ Javaアプリ上に配置した「Port Closeボタン」を押下するとExceptionが発生します。(ソースコード内の(★))
84
+
85
+ eclipse上のエラーログを見ると、test.dllが32bitでビルドされていない旨の指摘に見えますが、
86
+
87
+ 以下の記事を参考にtest.dllが32bitでビルドされていることは確認しています。
88
+
89
+ ※test.dllのバイナリデータを確認すると、「0x504500004C01」となっていること
90
+
91
+ http://sow23.blog.fc2.com/blog-entry-19.html
92
+
93
+
94
+
47
- Javaアプリから呼び出し、main関数内出力されるログを切り分けたす。
95
+ また、Javaアプリケーションも以下の記事を参考に32bitのJDKビルドしてす。
96
+
48
-
97
+ http://www.searchman.info/java_eclipse/1070.html
98
+
99
+
100
+
101
+
102
+
49
-
103
+ その他の原因としてどのようなことが想定されますでしょうか?
104
+
50
-
105
+ 継続して調査を行っておりますが、現状行き詰っている状態です。
106
+
107
+ 些細なアドバイスでもいただけますと助かります。
108
+
109
+
110
+
111
+ <ソースコード>
112
+
51
- C言語のソース
113
+ ```C言語
52
-
53
- ■hello.c
54
114
 
55
115
  #include <stdio.h>
56
116
 
57
- int main(int a, char** c){
58
-
59
- int flg=0;
60
-
61
- while(1){
62
-
63
- flg = getTest();
117
+ void test_Printf(){
64
-
65
-
66
-
67
- if(0==flg){
118
+
68
-
69
- printf("hello World: 01\n");
119
+ printf("hello World:test_Printf()\n");
70
-
71
- }
72
-
73
- else{
74
-
75
- setTest(0);
76
-
77
- printf("hello Workd: 02\n");
78
-
79
- }
80
-
81
- }
82
-
83
- return 0;
84
120
 
85
121
  }
86
122
 
87
- ■test.c
88
-
89
- #include <stdio.h>
90
-
91
- int testFlg=0;
92
-
93
- int getTest(){
94
-
95
- return testFlg;
96
-
97
- }
98
-
99
- void setTest(int a){
100
-
101
- testFlg = a;
102
-
103
- }
104
-
105
-
106
-
107
- ※Javaアプリケーション側のソース
108
-
109
- public class jw_test extends JFrame implements SerialPortEventListener{
110
-
111
- public interface CLibrary extends Library{
112
-
113
- CLibrary INSTANCE = (CLibrary)Native.loadLibrary("libtest.dll", CLibrary.class);
114
-
115
- void setTest(int a);
116
-
117
- }
118
-
119
- public static void main(String[] args) {
120
-
121
- EventQueue.invokeLater(new Runnable() {
122
-
123
- public void run() {
124
-
125
- try {
126
-
127
- jw_test frame = new jw_test();
128
-
129
- frame.setVisible(true);
130
-
131
- } catch (Exception e) {
132
-
133
- e.printStackTrace();
134
-
135
- }
136
-
137
- }
138
-
139
- });
140
-
141
- }
142
-
143
- public jw_test() {
144
-
145
- MainForm = this;
146
-
147
-
148
-
149
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
150
-
151
- setBounds(100, 100, 450, 589);
152
-
153
- contentPane = new JPanel();
154
-
155
- contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
156
-
157
- setContentPane(contentPane);
158
-
159
- contentPane.setLayout(null);
160
-
161
-
162
-
163
- btnPortClose = new JButton("Port Close");
164
-
165
- btnPortClose.addActionListener(new ActionListener() {
166
-
167
- public void actionPerformed(ActionEvent e) {
168
-
169
- textArea.setText("Port Close Clicked");
170
-
171
- if(commPort != null){
172
-
173
- commPort.close();
174
-
175
- }
176
-
177
- CLibrary.INSTANCE.setTest(1); ★アプリ上のCloseボタン押下でtest.c内の関数を呼び出したい
178
-
179
- }
180
-
181
- });
182
-
183
- }
184
-
185
- }
186
-
187
-
188
-
189
-
190
-
191
- <質問事項>
192
-
193
- Closeボタンを押下すると以下のエラーが発生しております。
194
-
195
- ただし、libtest.dllやhoge.exeは32bitで動作していることは以下の記事を参考に確認しています。
196
-
197
- http://sow23.blog.fc2.com/blog-entry-19.html
198
-
199
-
200
-
201
- Javaアプリケーションは、以下の記事を参考に32bitのJDKでビルドしています。
202
-
203
- http://www.searchman.info/java_eclipse/1070.html
204
-
205
-
206
-
207
- ★★
208
-
209
- ★★
210
-
211
- ★Javaアプリケーションが32bitでビルドされていないということでしょうか?
212
-
213
- ★回避策はございますでしょうか。
214
-
215
- ★しばらくgoogleで検索しましたが、現状解決の糸口すら見えていない状況です。
216
-
217
- ★★
218
-
219
- ★★
220
-
221
-
222
-
223
- ※エラーメッセージ
123
+ ```
124
+
125
+ ```Java言語
126
+
127
+ public class jw_test extends JFrame implements SerialPortEventListener{
128
+
129
+ public interface CLibrary extends Library{
130
+
131
+ CLibrary INSTANCE = (CLibrary)Native.loadLibrary("test.dll", CLibrary.class);
132
+
133
+ void test_Printf();
134
+
135
+ }
136
+
137
+ public static void main(String[] args) {
138
+
139
+ EventQueue.invokeLater(new Runnable() {
140
+
141
+ public void run() {
142
+
143
+ try {
144
+
145
+ jw_test frame = new jw_test();
146
+
147
+ frame.setVisible(true);
148
+
149
+ } catch (Exception e) {
150
+
151
+ e.printStackTrace();
152
+
153
+ }
154
+
155
+ }
156
+
157
+ });
158
+
159
+ }
160
+
161
+ public jw_test() {
162
+
163
+ MainForm = this;
164
+
165
+
166
+
167
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
168
+
169
+ setBounds(100, 100, 450, 589);
170
+
171
+ contentPane = new JPanel();
172
+
173
+ contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
174
+
175
+ setContentPane(contentPane);
176
+
177
+ contentPane.setLayout(null);
178
+
179
+
180
+
181
+ btnPortClose = new JButton("Port Close");
182
+
183
+ btnPortClose.addActionListener(new ActionListener() {
184
+
185
+ public void actionPerformed(ActionEvent e) {
186
+
187
+ textArea.setText("Port Close Clicked");
188
+
189
+ if(commPort != null){
190
+
191
+ commPort.close();
192
+
193
+ }
194
+
195
+ CLibrary.INSTANCE.test_Printf(); ★アプリ上のCloseボタン押下でtest.c内の関数を呼び出したい
196
+
197
+ }
198
+
199
+ });
200
+
201
+ }
202
+
203
+ }
204
+
205
+ ```
206
+
207
+ <エラーログ>
224
208
 
225
209
  Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: %1 は有効な Win32 アプリケーションではありません。
226
210
 
@@ -240,7 +224,7 @@
240
224
 
241
225
  at jw_estorq$CLibrary.<clinit>(jw_estorq.java:65)
242
226
 
243
- at jw_estorq$3.actionPerformed(jw_estorq.java:150)
227
+ at jw_estorq$3.actionPerformed(jw_estorq.java:151)
244
228
 
245
229
  at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
246
230
 
@@ -316,4 +300,4 @@
316
300
 
317
301
 
318
302
 
319
- 以上、よろしくお願いいたします。
303
+ 以上す。