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


Câu trả lời:


118

__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à dllimportdllexport. 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 .DEFtệ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)__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_EXPORTmacro thực hiện, giải quyết cho một trong hai Q_DECL_IMPORThoặc Q_DECL_EXPORT.


__declspec không đúng "dành riêng cho MS" (nó là "cụ thể cho trình biên dịch" hơn nhiều) và một số trình biên dịch cũng 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à dành riêng cho MS, vì DLL là MS lexicon).
Emilio Garavaglia

9
@Emilio: Theo như tôi biết, Microsoft đã phát minh ra __declspecký 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.
Cody Grey

8
Microsoft tạo ra một trình biên dịch. Nó được gọi là "Trình biên dịch Tối ưu hóa Microsoft C / C ++", cl.exe. Rất nhiều người gọi nhầm Visual Studio như thể nó là một trình biên dịch, nhưng đó là một IDE. Tôi không biết tại sao mọi người lại quan tâm đến ý nghĩa của "Microsoft-specific". Nó không có nghĩa là "môi trường MS" (bất cứ điều gì đó), và nó chắc chắn không có nghĩa là "Windows". Có, các nhà cung cấp trình biên dịch khác hiện hỗ trợ phần mở rộng để tương thích với cơ sở mã được cài đặt nhắm mục tiêu các trình biên dịch của Microsoft. Như tôi đã nói trước đây, theo như tôi biết, Microsoft đã phát minh ra cú pháp. Đó là điểm được thực hiện ở đây.
Cody Grey

2
@CodyGray: Chỉ riêng Microsoft đã phát minh ra nó sẽ không đủ. Tuy nhiên Microsoft đã phát minh ra nó, không có tiêu chuẩn nào chứa nó, những người khác chỉ triển khai nó để tương thích và nó được sử dụng chủ yếu (nếu không phải dành riêng) cho các chương trình nhắm mục tiêu Microsoft Windows cùng nhau tạo nên một điểm rất mạnh khi gọi nó là "Microsoft cụ thể"
celtschk

6
Đây là một câu trả lời tuyệt vời, đặc biệt là phần 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"! Làm cho mọi khía cạnh của nhập / xuất nội dung trở nên rõ ràng.
Ela782

30

__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).


6
Đồng ý. Cuối cùng, sau 2 giờ đọc, tôi đã tìm thấy câu nói hài lòng nhất, ngắn gọn nhất, chính xác nhất về điều tôi muốn.
el psy Congroo

1

__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


-2

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ụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.