Tôi hiện đang phát triển thư viện C++ cho Windows sẽ được phân phối dưới dạng tệp DLL. Mục tiêu của tôi là tối đa hóa khả năng tương tác nhị phân; chính xác hơn, các hàm trong DLL của tôi phải có thể sử dụng được từ mã được biên dịch với nhiều phiên bản của MSVC++ và MinGW mà không cần biên dịch lại DLL. Tuy nhiên, tôi nhầm lẫn về quy ước gọi điện nào là tốt nhất, cdecl
hoặc stdcall
.__cdecl hoặc __stdcall trên Windows?
Thỉnh thoảng tôi nghe các câu như "quy ước gọi C là người duy nhất được đảm bảo là cùng một trình biên dịch", tương phản với các câu như "There are some variations in the interpretation of cdecl
, particularly in how to return values". Điều này dường như không ngăn các nhà phát triển thư viện nhất định (như libsndfile) sử dụng quy ước gọi điện C trong các tệp DLL mà họ phân phối, mà không có bất kỳ sự cố rõ ràng nào.
Mặt khác, quy ước gọi stdcall
dường như được xác định rõ. Từ những gì tôi đã nói, tất cả các trình biên dịch Windows về cơ bản là cần thiết để làm theo nó bởi vì nó là quy ước được sử dụng cho Win32 và COM. Điều này dựa trên giả định rằng một trình biên dịch Windows mà không hỗ trợ Win32/COM sẽ không hữu ích lắm. Rất nhiều đoạn mã được đăng trên diễn đàn khai báo chức năng là stdcall
nhưng tôi không thể tìm thấy một bài đăng nào rõ ràng giải thích tại sao lý do tại sao.
Có quá nhiều thông tin xung đột ở đó và mọi tìm kiếm tôi chạy đều mang lại cho tôi các câu trả lời khác nhau, điều này thực sự không giúp tôi quyết định giữa hai câu hỏi. Tôi đang tìm kiếm một lời giải thích rõ ràng, chi tiết, có lý luận về lý do tại sao tôi nên chọn giải thích khác (hoặc tại sao hai cái này tương đương). Lưu ý rằng câu hỏi này không chỉ áp dụng cho các chức năng "cổ điển", mà còn cho các cuộc gọi hàm thành viên ảo, vì hầu hết mã khách hàng sẽ giao tiếp với DLL của tôi thông qua "giao diện", lớp ảo thuần túy (các mẫu sau được mô tả ví dụ: here và there).
"Có một số biến thể trong cách giải thích cdecl, đặc biệt là cách trả về giá trị" - điều này có nghĩa là các hệ điều hành khác nhau sử dụng cdecl trên x86 có thể sử dụng các biến thể khác nhau của cdecl, đó là các ABI khác nhau mà cả hai đều gọi là "cdecl" . Windows ghim các biến thể, bất kỳ triển khai nào chạy trên Windows và không tôn trọng các lựa chọn của Windows sẽ không thể gọi các hàm cdecl của Windows, vì vậy khi bạn nói với stdcall, nó vô dụng đối với lập trình Windows, và có một số tiêu chuẩn C các hàm sẽ khó triển khai. –