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

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

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

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

Q&A

0回答

563閲覧

GCJでネイティブコンパイルしたJavaで外部ライブラリを使う方法

BeatStar

総合スコア4958

Java

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

0グッド

1クリップ

投稿2019/08/20 02:54

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

とやると、上記で出てきたリンケージエラーになりました。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問