こんにちわ。
いつも教えてgooにお世話になっているorange_pieです。
UNIX上のC++で作成した自作ライブラリをdllにして配布したいのですが、
Unixでの基本的な考え方を教えてください。
(1)Unix上ではDLLの標準的な名称は”libxxxx.so”とするのが普通ですか?
※この形式ならLD_LIBRARY_PATH環境変数が検索してくれる。。。
(2)通常、DLLにする場合、インポートライブラリ(.lib)と実際のライブラリ(.so)を作成して、使用する側はインポートライブラリのみをリンクするのでしょうか?
(3)配布されたdllを使う側では、Link時にインポートライブラリをリンクして、関連インクルードファイルをインクルードするだけで使えるのでしょうか?
(4)上記の(2)のように、インポートライブラリとライブラリの実態を作成する為のコンパイルオプションが見つかりません。(ldのmanを見たのですが、意味がわからないと言うか。。。。。)
この質問は、自作ライブラリからlibxxx.soという形のオブジェクトファイルを作り、別プログラムからこのlibxxxをコンパイルオプション(-l)でリンクしてみたら正しく動作したのですが、これでは結局ライブラリの本体が一緒にリンクされている様子で、出来上がった実行形式のファイルサイズが静的ライブラリとしてリンクした時と同じ大きさになっていることに疑問を抱いてしまったものです。
この状態でも、ライブラリの方だけコンパイルしなおして実行すると
ちゃんとライブラリの変更点は反映されるので問題は無いのですが、
これでもダイナミックリンク・ライブラリと呼べるのでしょうか?
No.3ベストアンサー
- 回答日時:
# すっごく暇ってわけではないんですが :-)
> -Wl,-B,dynamic -lclntsh -ldl -lm -lnsl -lsocket -lrt -lpthread
>
> この中の”-B, dynamic ”の辺りが「ライブラリをダイナミックにリンクするよ」ってことだったのでしょうか?
man ld の -l と -B のところを読めば分かると思いますが、大体、そういうことです。
-B dynamic の場合(普通は、こっちがデフォルト)には -lxxx の指定で libxxx.so
を探して、無ければ、libxxx.a を探します。-B static の場合には libxxx.so を
対象にしません。
参考URLには solaris の AnswerBook を紹介しておきます。
> ということも考慮に入れると、arコマンドで作ったアーカイブもDLLもリンクオプションで-B dynamic とすれば、実行時にリンクできる。(のかな?)
いやいや。静的なライブラリ、っつう位ですから、静的なリンクにしか使え
ません。
.a も .so も「ライブラリ」って名前がつきますけれど、.a はアーカイブファイル
なので、tar の出力ファイルの方に似ています。.so の方は、実行形式のヘッダを
持ち ELF というフォーマットのファイルで実行バイナリの方に似ています。
> で、他人に提供するのにアーカイブとDLLのどちらが適しているかというと、
> 関数などが増えた場合以外はどちらでも同じ(という感じ?なのかな?)
その「他人」の環境次第なんですが、相手の OS やバージョンが特定できないと
静的なアーカイブの方が、利用できる可能性が少し広いです(ソース提供には
遠く及ばないですが)。
> arコマンドは、複数のオブジェクト(.o)を追加することで作成しなおすことができるが、DLLはライブラリ構成プログラムをリコンパイルする必要がある。
リコンパイルではなく、再リンクです。
後、共有ライブラリの場合には、あまり小さく刻んでしまうとロードの時間が
気になり出すので、ひとつのファイルの単位をどうするかを悩むときがあり
ます。
最後に、No.2 の回答にあるように unix をひと括りにして、.so が普通、と
言うのは、ちょっと大雑把すぎました。他の質問のことが頭にあったもので
orange_pie さんが使っている環境を暗に想定してました。
十年くらいさかのぼっただけで共有ライブラリが扱えない unix なんてのは、
ごろごろしてましたし。
参考URL:http://docs.sun.com:80/ab2/coll.153.4/REFMAN1/@A …
本当にお忙しいのに、ありがとうございます。いつもいつも。。。 (。・_・。)
>a も .so も「ライブラリ」って名前がつきますけれど、.a はアーカイブファイル
>なので、tar の出力ファイルの方に似ています。.so の方は、実行形式のヘッダを
持ち ELF というフォーマットのファイルで実行バイナリの方に似ています。
すばらしいです!!すっきり解決。すんなり納得。もう混乱しません。
どうしたら、こんなに正しい知識を幅広くお持ちになれるんでしょう。。。
もしかして、教授さん?
これからは、ぷろくまさんと呼ばせていただきます。(私だけ。)
参考URLは、Solaris上でmanコマンドを叩いたのと同じ情報のようですね。
これなら、いちいちターミナルからSolarisに接続しなくても良いので早速「お気に入り」に入れちゃいました。
本当にありがとうございました。
No.2
- 回答日時:
a-kumaさんの回答でだいたい良いのですが、
> (1)Unix上ではDLLの標準的な名称は”libxxxx.so”とするのが普通ですか?
これはUNIXの種類によります。SolarisやLINUXではその通りですが、HP-UXなどでは
libxxx.shになったりします。
あとlibxxx.aは静的ライブラリです。-B dynamic というリンクオプションが無ければ
こちらがリンクされます。-B static と明示的に指定することもできます。
は~。なるほど~。です。
”.a”と言ったら一般的に静的だと思えばよいのですね。
それならばやはり”.so”です。
ちなみにSolarisでの開発なので、libxxxx.soと言う形にしました。
このようなルールって、厳密に決められている訳ではなくて
”通常、こうだよね”というような、経験者の方に聞かなければ分からないことが多いような気がします。
無事にdllを作成して、配布できるまでに至りました。
みなさんのおかげです。
本当にありがとうございました。
No.1
- 回答日時:
> (1)Unix上ではDLLの標準的な名称は”libxxxx.so”とするのが普通ですか?
そうです。
OS によっては、libxxx.so は、libxxx.so.バージョン番号 というファイルへの
シンボリックリンクになってたりしますが、ローダが *.so というファイルを
探しに行くことが基本なのは一緒です。
> (2)通常、DLLにする場合、インポートライブラリ(.lib)と実際のライブラリ(.so)を作成して、使用する側はインポートライブラリのみをリンクするのでしょうか?
unix では、インポートライブラリなんて不細工なものは気にしなくても良いです。
直接、共有ライブラリがリンクできることは経験した通り。
> (3)配布されたdllを使う側では、Link時にインポートライブラリをリンクして、関連インクルードファイルをインクルードするだけで使えるのでしょうか?
インポートライブラリなんてものが要らないのは (2) の回答で書いた通り。
インクルードファイルが必要なのは、C/C++ で共通の定数やプロトタイプが
記述してあるから、という理由なだけで、「DLLを使う」ための必須の条件では
ありません。
> (4)上記の(2)のように、インポートライブラリとライブラリの実態を作成する為のコンパイルオプションが見つかりません。(ldのmanを見たのですが、意味がわからないと言うか。。。。。)
というわけで、unix のマニュアルを見ても永遠に分かることはないでしょう。
> これでは結局ライブラリの本体が一緒にリンクされている様子で、出来上がった実行形式のファイルサイズが静的ライブラリとしてリンクした時と同じ大きさになっている
ちょっと信じられません。
> ライブラリの方だけコンパイルしなおして実行するとちゃんとライブラリの変更点は反映される
ということから、共有ライブラリとしてはきちんと作成されているようです。
多分、静的なライブラリをリンクしたつもりになっているだけで、動的な
ライブラリがリンクされているはずです。
ld の man などに、libxxx.a と libxxx.so の両方が存在しているときの
動作について説明があるはずです。libxxx.so を削除してしまってから
もう一度、リンクをしてみてください。
実際にモジュールの参照が静的に解決されているかどうかは、nm という
コマンドで確認することが出来ます。
なるほど~。
インポートライブラリって、確かOS/2だかWindowsだかでDLLを作った時に「作れ!!」と言われたような気がして、Unixでも「そうなのかな~」と漠然と思ってしまいました。気にしなくてよかったのですね。
それから、
>多分、静的なライブラリをリンクしたつもりになっているだけで、
>動的なライブラリがリンクされているはずです。
についてですが、静的なライブラリをリンクしていたつもりのMakefileを見直して見たところ、Linkオプションに以下のように指定してありました。
-Wl,-B,dynamic -lclntsh -ldl -lm -lnsl -lsocket -lrt -lpthread
この中の”-B, dynamic ”の辺りが「ライブラリをダイナミックにリンクするよ」ってことだったのでしょうか?
そうだとすると、「静的にリンクしていたつもりで、実はもともと動的にリンクしていた」ということになり、サイズが同じという疑問が解けてすっきりします。
ん?
それでは、".a”と”.so”の違いってなんでしょう?
以前、くまさんが教えてくださった、
>ar コマンドで作成されるアーカイブとは違って、DLL は「リンクされたもの」 ですから、必要なオブジェクトファイルが増減したときには、追加・削除では
なく、常に再リンクをすることに注意してください。
ということも考慮に入れると、arコマンドで作ったアーカイブもDLLもリンクオプションで-B dynamic とすれば、実行時にリンクできる。(のかな?)
で、他人に提供するのにアーカイブとDLLのどちらが適しているかというと、
関数などが増えた場合以外はどちらでも同じ(という感じ?なのかな?)
arコマンドは、複数のオブジェクト(.o)を追加することで作成しなおすことができるが、DLLはライブラリ構成プログラムをリコンパイルする必要がある。
ということになるのでしょうか?
Unix的に美しいのは、.soですよね。きっと。
あ~。長々とすみません。
いろいろありがとうございます。
くまさんもお忙しいでしょうから、お返事はすっごく暇なときがあったらで
良いです。お返事がなくても自分でアーカイブとDLLの違いくらいは理解できるように探求します。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#でログファイルにファイルパ...
-
大量のデータを読み込んで表示...
-
Windows Formアプリからコンソ...
-
逆コンパイルと逆アセンブルの...
-
double型が正常に認識されてい...
-
パソコン
-
UART通信の取説で,left floati...
-
gccを行ってもexeファイルが生...
-
プログラミング言語についてc++...
-
次の記述について
-
C言語について。
-
応用情報技術者試験の令和元年...
-
右ビットシフト
-
C言語 配列と関数の練習問題
-
Notepad++の関数リスト表示でC...
-
Bitcoin、BTCはブロックチェー...
-
C++6.0でのresource.hについて
-
トリプトファンってケト原性あ...
-
MACで動く実行ファイルをWindow...
-
LinuxカーネルのCFSで用いられ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UNIX上のプログラムで使うライ...
-
拡張子.niiのファイルの開き方...
-
.NET(C#)でのスタックオーバー...
-
オブジェクトライブラリ
-
DXライブラリの画像の表示の仕...
-
Excel VBA のstr()関数でエラー
-
MakefileのLDLIBSとLOADLIBESの...
-
ライブラリParamQuery gridにつ...
-
pthreadのソースの入手方法
-
Googlemapのように画像を拡大・...
-
QRコード作成ライブラリ
-
ライブラリ内の処理中における...
-
自作ライブラリの作成方法
-
Unsatisfied code symbol エラ...
-
ライブラリとAPIについて
-
PDFファイルの文字を取得するプ...
-
コンパイル時のエラー
-
windows media playerでdropbox...
-
C++BuilderやDelphiでVC++用の...
-
jpegのバイナリデータを見る方法
おすすめ情報