Mã sau đây là từ một ứng dụng hiện có phải được biên dịch trong cả C và C++. Có một vĩ mô:Vui lòng giải thích vectơ hardcore này để đúc và đánh máy
/* Type-checking macro to provide arguments for CoCreateInstance() etc.
* The pointer arithmetic is a compile-time pointer type check that 'obj'
* really is a 'type **', but is intended to have no effect at runtime. */
#define COMPTR(type, obj) &IID_##type, \
(void **)(void *)((obj) + (sizeof((obj)-(type **)(obj))) \
- (sizeof((obj)-(type **)(obj))))
được sử dụng như sau:
ISomeInterface *object;
CoCreateInstance(&CLSID_SomeInterfaceImpl, NULL,
CLSCTX_INPROC_SERVER, COMPTR(ISomeInterface, &object))));
đây ý tưởng là hai tham số cuối cùng của CoCreateInstance()
là IID&
và void**
và grabs vĩ mô ISomeInterface**
và chuyển đổi nó để IID&
và void**
đồng thời thực thi kiểm tra thời gian biên dịch địa chỉ được chuyển tại vị trí ISomeInterface**
thực sự là địa chỉ của biến con trỏ ISomeInterface*
.
Được rồi, nhưng nhu cầu
((obj) + (sizeof((obj)-(type **)(obj))) \
- (sizeof((obj)-(type **)(obj)))
biểu hiện phức tạp là những gì? Tôi thấy rằng việc kiểm tra loại được thực thi với (obj)-(type**)(obj)
biểu hiện con. Cần thêm và sau đó trừ số sizeof()
là gì? Và cần phải đúc gì để void*
trước khi truyền tới void**
?
Tôi cho rằng như vậy có thể được thực hiện như sau:
#define COMPTR(type, obj) &IID_##type, \
(void **)(sizeof((obj)-(type**)(obj)), obj)
đây phần đầu của nhà điều hành dấu phẩy sẽ chứa một sizeof()
đó sẽ thực thi các typecheck và đánh giá để một hằng số, phần thứ hai sẽ chỉ mang lại cùng một con trỏ và con trỏ sẽ được truyền tới void**
.
Macro gốc có thể làm những gì tôi đề xuất không thể? Sự cần thiết cho những biến chứng đó là gì?
Và đây là lý do tại sao đây là mã không hợp lệ. Hãy để tôi đoán, bạn đã đấu tranh với điều này cả ngày? – orlp
@nightcracker: Không, tôi không duy trì mã đó, tôi chỉ tìm thấy nó và tò mò nó hoạt động như thế nào. – sharptooth
+1 cho phần cứng trong tiêu đề, phải là một thẻ! –