__Declspec là gì và khi nào tôi cần sử dụng nó?


157

Tôi đã thấy các trường hợp __declspectrong mã mà tôi đang đọc. Nó là gì? Và khi nào tôi cần sử dụng cấu trúc này?


1
Nếu bạn không may mắn và chuyển từ Linux sang Windows, bạn có thể lãng phí thời gian để tìm hiểu lý do tại sao DLL của bạn không hoạt động, cho đến khi bạn thấy rằng bạn phải thêm __declspec(dllexport)trước mỗi chức năng trong thư viện của mình
SomethingS Something

Câu trả lời:


74

Đây là một phần mở rộng cụ thể của Microsoft cho ngôn ngữ C ++, cho phép bạn gán một loại hoặc chức năng với thông tin lớp lưu trữ.

Tài liệu

__declspec (C ++)


19
Cảm ơn - nhưng tôi sẽ sử dụng nó để làm gì?
Scott J

4
Ví dụ, để khai báo các giao diện và lớp COM, bạn sử dụng __declspec (uuid), để xuất các hàm sans một tệp DEF bạn sử dụng __declspec (dllexport), v.v. Danh sách đầy đủ khá dài.
Seva Alekseyev

1
@ScottJ Tôi liên tục sử dụng nó cho các thuộc tính: __declspec (property (get = X put = X)) định danh kiểu dữ liệu. MSDN có nhiều chi tiết hơn của khóa học. Là một "lập trình viên C # đến C / C ++", đó là một niềm hạnh phúc!
MasterMastic

51

Các ví dụ chính tắc là __declspec(dllimport)__declspec(dllexport), hướng dẫn trình liên kết nhập và xuất (tương ứng) một ký hiệu từ hoặc sang DLL.

// header
__declspec(dllimport) void foo();


// code - this calls foo() somewhere in a DLL
foo();

( __declspec(..)chỉ kết thúc nội dung cụ thể của Microsoft - để đạt được khả năng tương thích, người ta thường sẽ gói nó bằng macro)


8
@tetris, bạn không biết từ mã. Quyết định được đưa ra bởi trình liên kết, người sẽ chọn người đầu tiên .libtìm thấy có biểu tượng xuất khẩu phù hợp.
Euro Micelli

19

Nó chủ yếu được sử dụng để nhập các biểu tượng từ / xuất biểu tượng vào thư viện dùng chung (DLL). Cả trình biên dịch Visual C ++ và GCC đều hỗ trợ __declspec(dllimport)__declspec(dllexport). Các cách sử dụng khác (chỉ một số Microsoft) được ghi lại trong MSDN .


12

Một ví dụ khác để minh họa từ khóa __declspec :

Khi bạn đang viết Trình điều khiển hạt nhân Windows, đôi khi bạn muốn viết các chuỗi mã prolog / epilog của riêng mình bằng mã trình biên dịch mã nội tuyến , do đó bạn có thể khai báo hàm của mình bằng thuộc tính trần .

__declspec( naked ) int func( formal_parameters ) {}

Hoặc là

#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}

Vui lòng tham khảo trần truồng (C ++)


8

Về cơ bản, đó là cách Microsoft giới thiệu các phần mở rộng C ++ của mình để chúng không xung đột với các phần mở rộng của C ++ tiêu chuẩn trong tương lai. Với __declspec, bạn có thể gán một hàm hoặc lớp; ý nghĩa chính xác khác nhau tùy thuộc vào bản chất của __declspec. __declspec (trần trụi), ví dụ, ngăn chặn việc tạo prolog / epilog (đối với các trình xử lý ngắt, mã nhúng, v.v.), __declspec (luồng) tạo ra một luồng cục bộ biến, v.v.

Danh sách đầy đủ các thuộc tính __declspec có sẵn trên MSDN và thay đổi theo phiên bản trình biên dịch và nền tảng.


1
Xem xét các trình biên dịch không phải microsoft như GCC 4.2, cung cấp giải pháp thay thế ngoài __attribute__ ((dllexport))việc __declspec(dllexport), chúng có công bằng khi gọi __declspec, một phần mở rộng chỉ dành cho Microsoft không?
dùng2338150

0

Tôi biết đã tám năm nhưng tôi muốn chia sẻ đoạn mã này được tìm thấy trong MRuby cho thấy làm thế nào __declspec()con ong có thể sử dụng ở cùng cấp độ với export keyword.

/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif
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.