gcjを試しています。
(以前、javacでやる方のJavaに挑戦していましたが、PCの不調でデータが...もちろんコンパイラも...)
(なので、gcjをDLしてやってみました...)
やりたいこと(概要):
POI等のような外部ライブラリや独自のライブラリをjarファイル(またはDLLファイル)にして、
GCJでJavaをネイティブコンパイルして作ったEXEファイル(実行ファイル)からアクセスしたい.
つまり、mainメソッドがあるクラスをネイティブコンパイルして、
外部ライブラリにアクセスするにはどうすればいいか.
参考1, 参考2を参考にして、gcjなるコンパイラでJavaをネイティブコンパイルしようとしています。
上記リンクを読んで、
■ (ネイティブコンパイルとして)コンパイルのみ
■ コンパイル及びリンクでネイティブ(*.exe)にする
は辛うじてできました。
ですが、通常のJavaならjarファイルのように、CやC++であればDLLのように
実行ファイルとは別のライブラリとして存在するものを使う場合ってどのようにすればいいのでしょうか?
http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcj-3.2.1/gcj-ja_3.html
を読んで私なりに考えてみました。
まず、構成。
( /.../ はディレクトリとしています )
/Project1/ + /RELEASE/ + Main.exe + <その他の必要なファイル> + Main.java + Class1.java + Compile.bat
となっています。
Compile.batは、まあ、makefileみたいに使うバッチファイルです。
コンパイル(及びリンク)が完了したらRELEASEディレクトリに存在する状態です。
Comopile.batを使って、
最初に Class1.javaをclassファイルにします。それをRELEASEディレクトリに移動。
次にMain.javaをMain.exe にしてRELEASEディレクトリに移動。
という風にしました。
一応、コードも載せておきます。
// Class1.java public class Class1{ public Class1( String name ){ name_ = name; } public void print(){ System.out.println( "俺は" + name_ + "だ" ); } private String name_; }
// Main.java class Main{ public static void main(String args[]){ Class1 obj = new Class1("BeatStar"); obj.print(); } }
これで、
Class1.javaコンパイル時には
$gcj -C Class1.java
とし、
Main.javaコンパイル時には
$gcj --main=Main -s -o .\RELEASE\Main.eXe Main.java
としました。すると、
// エラー C:\~\AppData\Local\Temp/cciSeaaa.o: In function `ZN4Main4mainEJvP6JArrayIPN4java4lang6StringEE':C:/~/003/Main.java:(.text+0x16): undefined reference to `Class1::class$' :C:/~/003/Main.java:(.text+0x2e): undefined reference to `Class1::Class1(java::lang::String*)' collect2: ld returned 1 exit status
という風に「リンケージエラー」になり、
クラスパスが足りないのかと思い、--classpath=Class1.classを追加して実行ファイル化.
そうすると、
// エラー Main.java:3: error: Type 'Class1' not found in the declaration of the local variable 'obj'. Class1 obj = new Class1("BeatStar");
とエラー。
多分、パッケージ名が合わないとかそういう理由かと思い、Project1直下にlibディレクトリを置き、
そこにClass1.javaを置いて、
Class1.javaのヘッダ部分にpackage libと書き、
Class1.javaを先にコンパイルしてRELEASEディレクトリにもlibディレクトリを置いてそこにClass1.classをコピー.
もちろん、Main.javaでのClass1生成は lib.Class1としてあります。
// コンパイル時
$gcj --main=Main -s -o .\RELEASE\Main.eXe Main.java --classpath=lib
それでも 上記の "Type 'Class' not found..." のメッセージ。
--classpath=lib/ や --classpath=lib/Class1 、そして --classpath=lib/Class.class としてみましたが、
それでも変わらない...
やっぱり、JNIとかそういうのを使って...とかになるのでしょうか?
もしjarファイル(あるいはjarファイルをDLLファイルにして)をネイティブ(Java)から使えるなら、
自分なりのライブラリや外部ライブラリが使いやすくなるのになぁ...と。
ちなみにgcj --versionとした場合。
C:\~>gcj --version gcj (GCC) 4.3.0 20061204 (experimental) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[情報]
言語: Java
コンパイラ: gcj (GCC) 4.3.0
OS: Windows10
[追記0]
-shared をつけて、外部ライブラリに相当するClass1.javaをDLLにして、
rem test.dllとする $gcj --main=Main -s -o .\RELEASE\Main.eXe Main.java -ltest
とやると、上記で出てきたリンケージエラーになりました。
あなたの回答
tips
プレビュー