2012-01-14 18 views
62

tôi thấy mã nguồn Qt như thế này:__declspec (dllimport) thực sự có nghĩa là gì?

class Q_CORE_EXPORT QBasicAtomicInt 
{ 
public: 
... 
}; 

nào Q_CORE_EXPORT định nghĩa vĩ mô như dưới đây:

define Q_DECL_IMPORT __declspec(dllimport) 

Vậy __declspec(dllimport) thực sự nghĩa là gì?

+2

bản sao có thể có của [Tại sao/khi nào __declspec (dllimport) không cần thiết?] (Http://stackoverflow.com/questions/4489441/why-when-is-declspec-dllimport-not-needed) –

Trả lời

84

__declspec là thuộc tính dành riêng cho Microsoft cho phép bạn chỉ định thông tin lớp lưu trữ.
(Góc của Nitpicker: Tuy nhiên, một số nhà cung cấp trình biên dịch khác — ví dụ như GCC — bây giờ hỗ trợ phần mở rộng ngôn ngữ này cho khả năng tương thích với cơ sở mã được cài đặt nhắm vào trình biên dịch của Microsoft. Một số thậm chí cung cấp các thuộc tính lớp lưu trữ bổ sung.)

Hai trong số các thuộc tính lớp lưu trữ có thể được chỉ định là dllimportdllexport. Điều này chỉ ra cho trình biên dịch rằng một hàm hoặc đối tượng được nhập khẩu hoặc xuất khẩu (tương ứng) từ một DLL.

Cụ thể hơn, chúng xác định giao diện của DLL cho máy khách mà không yêu cầu tệp định nghĩa mô-đun (.DEF). Hầu hết mọi người thấy việc sử dụng các phần mở rộng ngôn ngữ này dễ dàng hơn nhiều so với việc tạo các tệp DEF.

Vì lý do hiển nhiên, __declspec(dllimport)__declspec(dllexport) thường được ghép nối với nhau. Bạn sử dụng dllexport để đánh dấu một biểu tượng được xuất từ ​​tệp DLL và bạn sử dụng dllimport để nhập biểu tượng đã xuất đó vào tệp khác.

Vì điều này và vì cùng một tệp tiêu đề thường được sử dụng khi biên dịch DLL và mã khách hàng tiêu thụ giao diện của DLL, đây là một mẫu phổ biến để xác định macro tự động phân giải đến trình chỉ định thuộc tính thích hợp tại thời gian biên dịch. Ví dụ:

#if COMPILING_DLL 
    #define DLLEXPORT __declspec(dllexport) 
#else 
    #define DLLEXPORT __declspec(dllimport) 
#endif 

Sau đó đánh dấu tất cả các biểu tượng cần xuất với DLLEXPORT.

Có lẽ, đó là những gì mà macro Q_CORE_EXPORT thực hiện, giải quyết hoặc Q_DECL_IMPORT hoặc Q_DECL_EXPORT.

+0

__declspec không phải là đúng "MS-cụ thể" (nhiều hơn "trình biên dịch cụ thể) và một số trình biên dịch sử dụng khai báo này cho nhiều nền tảng. Một số giá trị thuộc tính là (dllexport/dllimports là MS cụ thể, trên thực tế, vì DLL là MS lexicon –

+5

@Emilio: Theo như tôi biết, Microsoft đã phát minh ra ký hiệu '__declspec' như một phần mở rộng cho ngôn ngữ C++.Tôi tin rằng GCC bây giờ hỗ trợ nó, nhưng đó là chủ yếu cho các lý do tương thích với các trình biên dịch của Microsoft. Và tôi không hiểu làm thế nào "MS cụ thể" là bất kỳ khác nhau từ "trình biên dịch cụ thể". Microsoft đã viết một trình biên dịch C++ và rất nhiều người sử dụng nó. Nó đi kèm với Visual Studio. –

+0

MS-cụ thể có nghĩa là "cụ thể đối với môi trường MS", trong khi "trình biên dịch cụ thể" có nghĩa là "cụ thể cho một trình biên dịch đã cho, không phải cho tất cả". Bây giờ, vì không có trình biên dịch MS không sử dụng __declspec, nó không thể nói -stricly speacking-MS cụ thể. (lưu ý: có một số __declspec cho GCC rằng các realte cho Linux là tốt, vì vậy nó thậm chí không chỉ là một vấn đề Windows ...). Những gì bạn nói là lịch sử đúng, nhưng không phải là "ngữ nghĩa". –

1

Điều đó có nghĩa là định nghĩa của hàm nằm trong thư viện động. Tham khảo the documentation để biết thêm chi tiết và ví dụ.

10

__declspec(dllimport) là bộ định danh lớp lưu trữ cho trình biên dịch biết rằng một hàm hoặc đối tượng hoặc kiểu dữ liệu được định nghĩa trong một DLL bên ngoài.

Hàm hoặc đối tượng hoặc kiểu dữ liệu được xuất từ ​​một DLL với __declspec(dllexport) tương ứng.

+1

Ok. Cuối cùng, sau 2 giờ đọc, tôi đã tìm thấy câu trả lời chính xác nhất, ngắn gọn nhất, chính xác nhất về những gì tôi muốn. –