2009-11-26 26 views
22

Cho đến một thời gian trước, tôi nghĩ thư viện tĩnh là một tập hợp các tệp đối tượng .o, chỉ lưu trữ chúng và không xử lý chúng khác nhau. Nhưng liên kết với một đối tượng .o và liên kết với một thư viện tĩnh .a chứa đối tượng .o này có vẻ không giống nhau. Và tôi không hiểu tại sao ...Khởi tạo tĩnh và hủy diệt các ảnh toàn cục của thư viện tĩnh không xảy ra với g ++

Hãy xem xét các tập tin mã nguồn sau đây:

// 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; 

Hãy biên dịch và liên kết và chạy này mã:

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

Hàm khởi tạo là hàm hủy của đối tượng gObject toàn cầu được gọi.

Bây giờ hãy tạo một thư viện tĩnh từ mã của chúng tôi và sử dụng (liên kết) trong một chương trình khác:

g++ -Wall -c object.cpp main.cpp 
ar rcs lib.a object.o 
g++ -Wall -o main2 main.o lib.a 
./main2 
> main 
  • constructor và destructor gObject của không gọi là ... tại sao?
  • Làm cách nào để chúng tự động được gọi?

Cảm ơn.

Trả lời

29

.a thư viện tĩnh chứa một số .o nhưng chúng không được liên kết trừ khi bạn tham chiếu chúng từ ứng dụng chính.
.o luôn tồn tại liên kết độc lập.

Vì vậy, .o tệp trong trình liên kết luôn đi vào bên trong, được tham chiếu hoặc không, nhưng từ .a tệp chỉ được tham chiếu .o tệp đối tượng được liên kết. Như một lưu ý, các đối tượng toàn cầu tĩnh không bắt buộc phải được khởi tạo cho đến khi bạn thực sự tham chiếu bất cứ thứ gì trong đơn vị biên dịch, hầu hết các trình biên dịch sẽ khởi tạo tất cả chúng trước chính, nhưng yêu cầu duy nhất là chúng được khởi tạo trước bất kỳ hàm nào của đơn vị biên dịch được thực hiện.

+2

Cảm ơn. Dường như liên kết với tất cả các tệp .o chứa trong .a có thể bị ép buộc bằng cách sử dụng tùy chọn trình liên kết -Wl, - toàn bộ lưu trữ (hoặc -Wl, -all_load trên MacOSX) ... – moala

+1

Xem thêm -force_load cho MacOSX – moala

+0

Sẽ có bất kỳ vấn đề nào, nếu cả hai '1.o' và' 2.o' từ 'some.a' có hai biến toàn cầu có cùng tên? Chúng có thể được liên kết thành một tệp thực thi (xem xét các trường hợp: toàn cầu được gọi/không được giới thiệu từ tệp thực thi) không? –

Các vấn đề liên quan