Obecnie pracuję nad biblioteką C ++ dla systemu Windows, która będzie dystrybuowana jako biblioteka DLL. Moim celem jest maksymalizacja interoperacyjności binarnej; dokładniej, funkcje w mojej bibliotece DLL muszą być użyteczne z kodu skompilowanego z wieloma wersjami MSVC ++ i MinGW bez konieczności ponownej kompilacji biblioteki DLL. Jednak nie wiem, która konwencja dzwonienia jest najlepsza cdecl
lub stdcall
.
Czasami słyszę takie stwierdzenia, jak „Konwencja wywoływania w C jest jedyną, która gwarantuje, że będą takie same między kompilatorami”, co kontrastuje ze stwierdzeniami typu „ Istnieją pewne różnice w interpretacji cdecl
, szczególnie w zwracaniu wartości ”. Wydaje się, że nie powstrzymuje to niektórych deweloperów bibliotek (takich jak libsndfile ) przed używaniem konwencji wywoływania C w dystrybuowanych przez nich bibliotekach DLL, bez żadnych widocznych problemów.
Z drugiej strony stdcall
konwencja wywoływania wydaje się być dobrze zdefiniowana. Z tego, co mi powiedziano, wszystkie kompilatory Windows są zasadniczo zobowiązane do przestrzegania tego, ponieważ jest to konwencja używana dla Win32 i COM. Opiera się to na założeniu, że kompilator systemu Windows bez obsługi Win32 / COM nie byłby zbyt przydatny. Wiele fragmentów kodu opublikowanych na forach deklaruje funkcje, stdcall
ale nie mogę znaleźć ani jednego wpisu, który jasno wyjaśnia dlaczego .
Jest tam zbyt wiele sprzecznych informacji, a każde wyszukiwanie, które przeprowadzam, daje mi różne odpowiedzi, co tak naprawdę nie pomaga mi zdecydować między nimi. Szukam jasnego, szczegółowego, uzasadnionego wyjaśnienia, dlaczego powinienem wybrać jedno z nich (lub dlaczego oba są równoważne).
Zwróć uwagę, że to pytanie dotyczy nie tylko „klasycznych” funkcji, ale także wywołań funkcji wirtualnych, ponieważ większość kodu klienta będzie się łączyć z moją biblioteką DLL za pośrednictwem „interfejsów”, czystych klas wirtualnych (według wzorców opisanych np. Tu i tam ).