[C++] __cdecl o __stdcall en Windows?



Answers

La mayor diferencia en las dos convenciones de llamadas es que " _ _cdecl" coloca la carga de equilibrar la pila después de una llamada de función en la persona que llama, lo que permite funciones con cantidades variables de argumentos. La convención "__stdcall" es de naturaleza "más simple", pero menos flexible a este respecto.

Además, creo que los lenguajes administrados usan la convención stdcall por defecto, por lo que cualquier persona que use P / Invoke en él tendría que declarar explícitamente la convención de llamadas si usa cdecl.

Entonces, si todas sus firmas de funciones van a estar definidas estáticamente, probablemente me inclinaría hacia stdcall, si no cdecl.

Question

Actualmente estoy desarrollando una biblioteca C ++ para Windows que se distribuirá como una DLL. Mi objetivo es maximizar la interoperabilidad binaria; más precisamente, las funciones en mi DLL deben ser utilizables desde código compilado con múltiples versiones de MSVC ++ y MinGW sin tener que recompilar la DLL. Sin embargo, estoy confundido acerca de qué convención de llamadas es la mejor, cdecl o stdcall .

A veces escucho declaraciones como "la convención de llamadas C es la única garantizada para ser la misma en todos los compiladores", que contrasta con afirmaciones como " Hay algunas variaciones en la interpretación de cdecl , particularmente en cómo devolver valores ". Esto no parece detener a ciertos desarrolladores de bibliotecas (como libsndfile ) para usar la convención de llamadas C en las DLL que distribuyen, sin ningún problema visible.

Por otro lado, la convención de llamada stdcall parece estar bien definida. Según lo que me han contado, todos los compiladores de Windows básicamente deben seguirlo porque es la convención utilizada para Win32 y COM. Esto se basa en la suposición de que un compilador de Windows sin compatibilidad Win32 / COM no sería muy útil. Una gran cantidad de fragmentos de código publicados en foros declaran funciones como stdcall pero parece que no puedo encontrar una sola publicación que explique claramente por qué .

Hay demasiada información contradictoria, y cada búsqueda que hago me da respuestas diferentes que realmente no me ayudan a decidir entre los dos. Estoy buscando una explicación clara, detallada y argumentada sobre por qué debería elegir una sobre la otra (o por qué las dos son equivalentes).

Tenga en cuenta que esta pregunta no solo se aplica a las funciones "clásicas", sino también a las llamadas a funciones de miembros virtuales, ya que la mayoría de los códigos de cliente interactúan con mi DLL a través de "interfaces", clases virtuales puras (siguiendo los patrones descritos, por ejemplo, here y there ).






Links