静的リンクライブラリとは?ビルドされたライブラリを動的にリンクさせることは可能か?

このQ&Aのポイント
  • 静的リンクライブラリとは、ビルドされたライブラリを実行プログラムに静的にリンクさせるものです。
  • 動的リンクライブラリやDLLは、実行時にリンカがアドレス解決を行いますが、静的リンクライブラリではビルド時にリンカが必要な部分を解決します。
  • 静的リンクライブラリとしてビルドされたライブラリを動的にリンクさせることは、実装次第で可能ですが、一般的には静的リンクライブラリは静的にリンクされることを前提としています。
回答を見る
  • ベストアンサー

静的リンクライブラリについて

WindowsのライブラリにDLLやLIBといった形式があり、それぞれ「動的リンクライブラリ」「静的リンクライブラリ」となっていますが、 静的リンクライブラリとしてビルドされたライブラリを、動的に実行プログラムにリンクさせることは(Cやアセンブラなどの)実装次第で可能なのでしょうか? ビルド時にリンカがやってくれてることを実行時に行えればOK・・・という素直な話ではないのでしょうか。DLLも実行時にGetProcAddress()などを使ってアドレス解決をするわけですし、LIBでも同じことをするのは不可能ではないのでは?と思ったのです。 ※動的/静的リンクの概念や具体的な使用方法などはネット上で調べることができましたが、中身にまで踏み込んだ解説をしているページには巡り合えませんでした。そういう具体的な解説のあるページの紹介だけでもとても助かります。また、「根本的に思い違いをしてるんでは?」というご指摘も非常に助かります。 ※私自身↑に対する需要はないのでコスト・メリットとかは度外視です。興味本位というやつです。 ※別段、Windowsやライブラリの形式にこだわりがあるわけではないですが、これが一番メジャーだろう、ということでWindowsのDLL/LIBを対象に質問させて頂きました。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

プログラムがリンカの機能を内蔵すれば可能でしょう。同じくコンパイラを内蔵すればCソースコードをリンクして実行することもできます。 ファイルフォーマットは、DLLはEXEと同じでPE(Portable Executable)です。 LIBは、VCだとCOFFフォーマットだと思う。下記参照。 # http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx

htk433
質問者

お礼

コンパイラまで内蔵してしまったら、本当にそれはコンパイル言語なのか、よくわからなくなってしまいますね(笑) しかしまあ…プロセスの中でlibが生きてる時間は通常の静的なリンクと変わりがないわけで、それをもって「動的リンクした!」と言えるのかどうかは私としてはやや疑問のあるところです。 興味深い回答、ありがとうございました。

関連するQ&A

  • 静的/動的リンクライブラリについて

    Pythonのctypesを使っていてふと気になったので質問させていただきます。 Cと少々Java、程度の経験しかなかった私にとって、ctypesによって「Cのデータ型を利用できる」「dllをロードして、エクスポートされている関数を使用できる」というのは衝撃でした。 しかし、考えてみれば、仕組みとして理解できなくもない・・・かな?と現在は思っています。 ただ気になったのは、  ・どうして静的リンクライブラリ(.lib)の方は対応してないの? ということです。 [質問1]これは原理的に不可能なのでしょうか、それともctypesやPythonの仕様としてできないだけなのでしょうか。 (おそらくは「原理的に不可能」なのだろう、と個人的には思っておりますが・・・。) 以下は私の中の解釈ですが、 ・マシン語として実行可能な形式になっているdllは、実行時のリンクの機構さえ整っていれば別にC言語でなくともロードや中身のコードを利用することはできる。 ・また、Cのデータ型についても、要は型のバイト数やフォーマット(つまり内部的な扱われ方)をPythonインタプリタが押さえていれば良い話であるから、PythonでCの型を使用することは原理的に可能。 さて、 [質問2]それではlibはどうか。 libもコンパイル済みのものであるなら、Python(またはC以外の言語)からlib内のコードを利用することはできるのではないか? どちらかのみの回答でも結構です。 また、解釈の誤りについてのご指摘や、リンクライブラリの仕組みを解説したページを教えてくださると助かります。 よろしくお願いします。

  • ライブラリ内の処理中におけるライブラリリンクについて

    VC2005を使用しています。 ライブラリからライブラリファイルって使用できるんでしょうか? (例) A.lib内の処理に、B.DLLを明示的に読み込み処理 ----------------- <A.lib内の処理> hDLL = LoadLibrary("B.dll"); // DLLのロード if (hDLL != NULL) { ~ 処理実行 ~ } ----------------- 私の環境で何度やっても、GetLastErrorにて、 "7E"(ERROR_MOD_NOT_FOUND)が出力されます。 ロードしているパスに、B.dllは必ずあります。 上記の例は明示的リンクですが、暗黙的リンクでもかまいません。 ライブラリ処理の中でライブラリファイルを使用するには、 どうすれば良いでしょうか。 もしかして、ライブラリ内で他のライブラリを使用できない 等のオチもあるのでしょうか...。

  • Qtライブラリを静的にリンクしたい

    Qt 5.11.0 を使ってGUIアプリをつくろうとしているのですが、実行時の問題があります。 ソースは初心者用のサンプルソースコードで、Qt Creator を使って以下の「main.cpp」を作成しました。 #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } ウインドウ生成は「mainwindow.cpp」で、 #include "mainwindow.h" #include <Qtgui> #include <QtWidgets> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QLabel *label = new QLabel(tr("Hello World.")); setCentralWidget(label); } MainWindow::~MainWindow() { } となっています。 これをビルドして、Qt Creatorから実行するとウィンドウが表示されます。 しかし、単独で(ダブルクリックで)実行しようとすると 「コンピューターにQt5Cored.dllがないため、プログラムを開始できません。・・・」 というシステムエラーが表示され、実行できません。 これ以外に、mingwとmake を使って別のサンプルソースをコンパイルしても同様のエラーが出てきます。 実行ファイルと同じディレクトリにQt5Widgets.dll、Qt5Core.dll、Qt5Gui.dllの3つのDLLをコピーすると、実行できます。 しかし、いちいちDLLを要請するプログラム構成は好きでないのと、同名のライブラリlibQt5Widgets.a、libQt5Core.a、libQt5Gui.aがあることから、できれば静的にリンクしたいと思っています。 静的にリンクするために以下の4つの方法を試してみましたが、ことごとく失敗しています。 方法1 ライブラリを指定してリンク g++ -static -O0 -g -o Qt_test.exe Qt_test.obj -lmingw32 -LC:\Qt\5.11.0\mingw53_32\lib -lQt5Widgets -lQt5Core -lQt5Gui -lqtmain -LC:\utils\my_sql\my_sql\lib -LC:\utils\postgresql\pgsql\lib -lshell32 のような書式で、3つのライブラリの順番を入れかえて6パターン試しましたが、DLLエラーは変わりません。 方法2 ライブラリをld.exeでまとめたオブジェクトファイルを作ってリンク 「GNUソフトウェアプログラミング」という本の112ページにリンカ「ld」のオプションについての記述があり、オブジェクトファイルとライブラリ同士をリンクする方法が紹介されていたので試してみましたが、未解決の参照がない?のか、20バイトのファイルが出力されただけでした。 ld -static -r -o qtobj.o C:\Qt\5.11.0\mingw53_32\lib\libQt5Gui.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Widgets.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a ld -static -r -o qtobj.o -LC:\Qt\5.11.0\mingw53_32\lib -lQt5Gui -lQt5Widgets -lQt5Core 方法3 arでオブジェクトファイルを作る ar rs qto2.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Gui.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Widgets.a C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a でライブラリをまとめたファイルは作れるのですが、コンパイルするとリンク時に qto2.a: error adding symbols: Archive has no index; run ranlib to add one となり、うまくいきません。 方法4 Qt creator で静的リンク Qt Creatorで「ライブラリの追加」を行うと、「HelloWrold.pro」に以下の行が加わり、リンクできそうなのですが、実行時にやはりDLLを要求されます。 LIBS += -LC:/Qt/5.11.0/mingw53_32/lib/ -lQt5Core 結局は、Qtで静的なリンクを行う方法が知りたいのです。 ご助言をお願いいたします。 環境は、Win7、Mingw、QtはMingwパッケージオプションを付けてインストールしており、 「C:\Qt\5.11.0\mingw53_32\lib\libQt5Core.a」 「C:\Qt\5.11.0\mingw53_32\include」 「C:\Qt\5.11.0\mingw53_32\bin\Qt5Core.dll」 があり、中にDLLもライブラリもあります。 よろしくお願いします。

  • VC++2008でインポートライブラリのスタティックリンクの設定

    VC++2008でインポートライブラリのスタティックリンクの設定 従来のVC++6.0ではプロジェクトのビルド時にインポートライブラリをスタティックリンクさせる場合 「プロジェクト」メニューから「設定」項目を選択し、「プロジェクトの設定」ウィンドウを表示させて、 「リンク」タブをクリックして表示されるページの「オブジェクト/ライブラリモジュール」欄の先頭に、 MyDll.lib(例)とスペースを1つ入力していました。末尾のスペースはMyDll.libとkernel32.libを区切るために必要でした。 これをVC++2008で実現するためにはどの様にしたらいいのですか? VC++2008の「プロジェクト」メニューを探しても「プロジェクトの設定」ウィンドウがありません。

  • スタティックライブラリのリンクについて

    「猫でもわかるWindowsプログラミングを買ったのですが、 VC++2008エクスプレスエディションで出来ると書いてあり 説明どうりやったのですが、スタティックライブラリのリンクをするように書いてあったのですが、リンクはわかったのですが、libファイル を出したいのに、出ません。本には、すべてのファイルが出ており、libファイルとリンクができているのですが、私がやってみたところ、 すべてのファイルができず、libファイルが表示されません。 すべてのファイルを出すにはどうしたらいいでしょうか?

  • スタティックリンクライブラリで2重リンクできる?

    スタティックリンクライブラリで2重リンクをしようとすると、warning LNK4006が発生してしまいます。 メッセージ: "~で定義されています; 2 つ目以降の定義は無視されます" 例えば、 aaa.libがbbb.libとccc.libをリンクしてて、bbb.libとccc.libはそれぞれddd.libをリンクしているとします。*.libはすべてスタティックリンクライブラリで提供を考えています。   [ aaa.lib ]    |   | [bbb.lib] [ccc.lib]   |     | [ddd.lib] [ddd.lib] 調べてみると「ライブラリーを結合する時に,このエラー・メッセージが表示された場合,ライブラリーに既に存在しているシンボルを追加しようとしています。」ということで、要は"ddd.lib"が重複してリンクされているという事のようなのですが、原因ばかりで解決策が分かりません。 LNK4006の解決法が分かれば良いのですが、最終的にはこの構成で"aaa.lib"だけで提供するようなライブラリを作成したいです。実現するためにはどのようにしたら良いのでしょうか?アイデアを頂けたら助かります。また詳しい方がいらっしゃいましたらご教授お願いいたします! ※Windows2000でVisualStadio.NET2003を使用してます。

  • VC++でビルド時の、リンク警告 LNK4006、LNK4221 を消したい

    こんにちは。 先週から仕事で Visual Stadio 2005 を使用して、C言語 でプログラムを書いています。 コードをビルドする際、ライブラリ作成時に以下の警告がでます。 1>Dynamic_02.lib(Dynamic_02.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR は Dynamic_01.lib(Dynamic_01.dll) で定義されています。2 つ目以降の定義は無視されます。 1>Dynamic_02.lib(Dynamic_02.dll) : warning LNK4221: パブリック シンボルが見つかりませんでした。アーカイブ メンバにアクセスできません。 これらの警告を消す方法はないですか? 以下は手順の詳細です。 1. 動的リンクライブラリ、Dynamic_01.dll を作成した。 同時にインポートライブラリ Dynamic_01.lib が作成される。 2. 動的リンクライブラリ、Dynamic_02.dll を作成した。 同時にインポートライブラリ Dynamic_02.lib が作成される。 3. Dynamic_01.dll と Dynamic_02.dll の両方の関数を使用する、 静的リンクライブラリ、Static_01.lib の作成を試みた。 追加の依存関係に Dynamic_01.lib と Dynamic_02.lib を指定し、 Static_01.lib をビルドすると、上記の警告が表示される。

  • 【C++】静的リンクと動的リンクの違い

    静的リンクと動的リンクの違いについて教えてください。 ググって、wikiにて確認したところ、 動的リンクは、実行時にプログラムの結合を行う。 静的リンクは、コンパイル直後の実行ファイル生成時に、ライブラリ等を全てリンクし、必要なコードが全て揃った実行ファイルを生成する。 というのはわかりました。 それを踏まえて、  (1)-(1)libファイルで静的リンクさせるケース   メソッドやプロパティのインデックスというかインタフェース仕様のみ書かれている。   そして、そのインデックスを元にコンパイルチェックを行っている。  (1)-(2)objファイルで静的リンクさせるケース   objには、.cppと、.h に書かれている処理のうち、そのソース本体(そのクラス自身のモノとして持っている処理)のプロパティやメソッドのことが機械語で書かれている。   プロパティやメソッドが書かれているため、当然インタフェース仕様もわかる。 であろうと捉えていますが、この認識で大雑把には合っていますでしょうか? また、DLLを使う場合、動的リンクとは呼ばれているものの、 「DLLでは、objに加え、必要なリンクの情報まで持っている」と思われるので、 結局、リンカによるリンク実行時に、インタフェースで不整合が起きていないかはチェックされているという認識なのですが、合っていますでしょうか?  (だとすると、なぜ、ある意味、DLLを使っていても静的リンクなのかなと感じ、動的リンクと呼ぶことに不自然さを感じます) 宜しくお願いいたします。 .

  • VS2013リンクするライブラリ一覧表示方法は?

    こんばんは。 Visual Studio 2013の初心者です。基本的なことで困っております。 どうかアドバイスをお願い申し上げます。 ・質問内容 プロジェクトに登録されているリンクするライブラリ名(*.lib)を確認する(一覧表示する)方法を教えて下さい。 ・背景 とある仕事を引きつぐことになりまして、貰ったVS2013のプロジェクト(ソース)をビルドしようとしましたが「****.lib」がありません。と出て来てリンクエラーになってしまいます。 足りないライブラリを追加してまたビルドすると別の「****.lib」がありません。と出てしまいます。この繰り返しです。 しかし、その都度「***.libファイルが足りない」と言って貰うのは、ウザがられるので一括して見る方法が判りません。 プロジェクトファイルでリンクに必要な「ライブラリの一覧」を見たいのです。そして、「これだけのlibが無いので欲しい」と一括して貰いたいのです。 しかし、lib名を検索掛けても何処にリンクに必要なライブラリ一覧が記録されているファイルが見つかりませんでした。 一体何処に記録されているのでしょうか? 色々web検索したのですがどうしても見つかりません。 大変、難儀しております。 宜しくお願い申し上げます。

  • ライブラリ??

    VCをつかってコーディングしています。 C言語仕様のネットワークプログラミングです。 socketをつくりデータのやり取りをするのですが gethostbyname()という関数が動作しません。 ちゃんとコンパイルもビルドもとおります。 ライブラリもwsock32.libやws2_32.libをリンクしています。 なにが原因なのかわかりません。 WINDOWSがまずいのでしょうか? 宜しくお願いします。

専門家に質問してみよう