24

少し前まで、私は .a スタティック ライブラリは .o オブジェクト ファイルの単なるコレクションであり、それらをアーカイブするだけで、別の方法で処理することはないと考えていました。しかし、.o オブジェクトとのリンクと、この .o オブジェクトを含む .a スタティック ライブラリとのリンクは明らかに同じではありません。そして、私はその理由を理解していません...

次のソース コード ファイルについて考えてみましょう。

// main.cpp
#include <iostream>
int main(int argc, char* argv[]) {
    std::cout << "main" << std::endl;
}

// object.hpp
#include <iostream>
struct Object
{
    Object() { std::cout << "Object constructor called" << std::endl; }
    ~Object() { std::cout << "Object destructor called" << std::endl; }
};

// object.cpp
#include "object.hpp"
static Object gObject;

このコードをコンパイルしてリンクし、実行しましょう。

g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called

グローバル gObject オブジェクトのコンストラクタおよびデストラクタが呼び出されます。

コードから静的ライブラリを作成し、それを別のプログラムで使用 (リンク) しましょう。

g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
  • gObject のコンストラクタとデストラクタが呼び出されない...なぜ?
  • それらを自動的に呼び出す方法は?

ありがとう。

4

1 に答える 1

33

.a静的ライブラリにはいくつか含まれて.oいますが、メイン アプリから参照しない限りリンクされません。
.oファイルは常にスタンドアロン リンクです。

その.oため、リンカー内のファイルは、参照されているかどうかにかかわらず、常に内部に入りますが、ファイルからは、参照されているオブジェクト ファイル.aのみがリンクされます。.o

注意として、コンパイル単位で実際に何かを参照するまで、静的グローバル オブジェクトを初期化する必要はありません。ほとんどのコンパイラは、メインの前にそれらすべてを初期化しますが、唯一の要件は、コンパイル単位の関数が取得される前に初期化されることです。実行されました。

于 2009-11-26T16:25:15.827 に答える