2009-08-18 26 views
8

typedef này:C++: typedefs Callback với __stdcall trong MSVC

typedef DWORD WINAPI 
(* CM_Open_DevNode_Key)(DWORD, DWORD, DWORD, DWORD, PHKEY, DWORD); 

biên dịch tốt trong BorlandCpp Tuy nhiên, khi tôi biên dịch nó trong msvc tôi phải loại bỏ WINAPI (mà chỉ là một bí danh cho __stdcall):

typedef DWORD 
(* CM_Open_DevNode_Key)(DWORD, DWORD, DWORD, DWORD, PHKEY, DWORD); 

Tại sao điều này lại xảy ra? Tôi có thể loại bỏ phần WINAPI một cách an toàn không?

Cập nhật: Tôi đã phải loại bỏ "WINAPI" hình thành typedef, nếu không tôi đã

error C2059: syntax error : '(' 

cho các dòng.

Bạn có thể cho tôi biết tại sao Borland có thể biên dịch nó bằng "WINAPI" trong khi Msvc không thể?

+0

Xin lỗi, bây giờ nó được bao gồm. – George

Trả lời

13

Tôi tin vào VC++ bạn cần đặt quy ước gọi bên trong() Đây là example trên MSDN sử dụng quy ước gọi bên trong một con trỏ hàm typedef.

typedef DWORD (WINAPI * CM_Open_DevNode_Key)(DWORD, DWORD, DWORD, DWORD, PHKEY, DWORD); 

Điều này sẽ biên dịch mà không gặp vấn đề gì.

+0

Cảm ơn bạn, công cụ này hoạt động:) – George

0

Con trỏ hàm phải có thông tin về quy ước gọi được sử dụng bởi hàm. Nếu bạn đang trỏ đến một hàm sử dụng quy ước gọi __cdecl, bạn phải sử dụng một con trỏ hàm __cdecl. Nếu bạn đang trỏ đến một hàm sử dụng quy ước gọi __stdcall, bạn phải sử dụng một con trỏ hàm __stdcall.

Hy vọng điều này sẽ hữu ích.

0

Lưu ý phụ: Tôi tin rằng các chữ ký hàm chức năng phải không bao giờ được thể hiện dưới dạng con trỏ typedefs.

Nếu bạn đã định nghĩa CM_Open_DevNode_Key là không-con trỏ, bất kỳ tuyên bố tiêu đề của một chức năng mà là làm theo chữ ký callback này có thể chỉ đơn giản là đã được viết như

CM_Open_DevNode_Key MyFunc;

chứ không phải là một quá verbose/dễ bị lỗi

DWORD WINAPI MyFunc (DWORD, DWORD, DWORD, DWORD, PHKEY, DWORD);

Điều này sẽ cho phép mã đơn giản hơn nhiều và nhiều kết hợp cụ thể hơn của chữ ký chức năng, nếu cần.

Chưa kể rằng typedefs con trỏ là ác nói chung vì chúng không cho phép xác định constness của nội dung được trỏ đến (ví dụ khét tiếng: "const PCHAR" so với "const CHAR *" được đánh giá đúng).