Tôi thấy mã nguồn Qt như thế này:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Q_CORE_EXPORT
Macro nào xác định như sau:
define Q_DECL_IMPORT __declspec(dllimport)
Vì vậy, những gì __declspec(dllimport)
thực sự có nghĩa là gì?
Tôi thấy mã nguồn Qt như thế này:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Q_CORE_EXPORT
Macro nào xác định như sau:
define Q_DECL_IMPORT __declspec(dllimport)
Vì vậy, những gì __declspec(dllimport)
thực sự có nghĩa là gì?
Câu trả lời:
__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 — hiện hỗ trợ phần mở rộng ngôn ngữ này để tương thích với cơ sở mã đã cài đặt được viết nhắm mục tiêu các trình biên dịch của Microsoft. Một số thậm chí còn 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à dllimport
và dllexport
. Chúng chỉ ra cho trình biên dịch rằng một hàm hoặc đối tượng được nhập hoặc xuất (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 .DEF
tệp định nghĩa mô-đun ( ). 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ì những lý do rõ ràng, __declspec(dllimport)
và __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 là được xuất từ DLL và bạn sử dụngdllimport
để nhập biểu tượng đã xuất đó vào một tệp khác.
Bởi vì điều này, và bởi vì cùng một tệp tiêu đề thường được sử dụng cả khi biên dịch DLL và trong mã máy khách sử dụng giao diện của DLL, đó là một mẫu phổ biến để xác định macro tự động phân giải thành trình chỉ định thuộc tính thích hợp tại thời điểm biên dịch. Ví dụ:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
Và sau đó đánh dấu tất cả các ký hiệu sẽ được xuất bằng DLLEXPORT
.
Có lẽ, đó là những gì Q_CORE_EXPORT
macro thực hiện, giải quyết cho một trong hai Q_DECL_IMPORT
hoặc Q_DECL_EXPORT
.
__declspec
ký hiệu như một phần mở rộng cho ngôn ngữ C ++. Tôi tin rằng GCC hiện đã hỗ trợ nó, nhưng đó chủ yếu là vì 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 "MS-cụ thể" có gì khác với "cụ thể cho trình biên dịch". 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.
__declspec(dllimport)
là một mã định nghĩa 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ừ DLL với một tệp tương ứng __declspec(dllexport)
.
__declspec(dllexport)
yêu cầu trình biên dịch thông báo cho trình liên kết rằng các ký hiệu này cần được đặt trong bảng xuất (khi biên dịch .dll). Khi biên dịch chương trình liên kết với .dll, __declspec(dllimport)
yêu cầu trình biên dịch tạo ra tuyệt đối rip-tương đối -gián lệnh gọi gián tiếp gián tiếp (mà trình liên kết sẽ điền quyết định trỏ đến bảng nhập) thay vì lệnh rip-tương đối đăng ký-trực tiếp thông thườnglệnh gọi gián tiếp đến một hàm không xác định (vì nó không thể sửa đổi lệnh, trình liên kết sẽ chèn địa chỉ tương đối của một cú đánh và sau đó tạo ra lệnh gọi, bên trong nó đặt lệnh gọi gián tiếp rip-tương đối-thanh ghi gián tiếp đến con trỏ hàm trong bảng nhập). Đây là một kích thước mã và tối ưu hóa tốc độ. Đó là thư viện nhập .lib cho trình liên kết biết các ký hiệu nào sẽ được nhập và được sử dụng làm hướng dẫn để tạo bảng nhập và tạo bất kỳ phần nào cần thiết trong phân đoạn .text.
https://docs.microsoft.com/en-us/cpp/build/importing- Chức năng-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / import-data-using-statementspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773
Nó có nghĩa là định nghĩa của hàm nằm trong một thư viện động. Tham khảo tài liệu để biết thêm chi tiết và ví dụ.