2010-12-28 11 views
14

yo estaba tratando de exportar una función de prueba simple para un DLL para trabajar con una aplicación (FYI: mIRC) que especifica la convención de llamada como:nombre stdcall mangling usando c extern y dllexport vs definiciones del módulo (msvC++)

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) 

Ahora, para llamar esto desde la aplicación, estaría usando test_func pero me he dado cuenta debido a que el nombre no funciona tan bien como había pensado.

A través de temas similares aquí he llegado a la comprensión de que el uso de extern "C" en combinación con __declspec (dllexport) es un método (un poco) de eliminar mangling al módulo definiciones (.def) equivelant. Sin embargo, cuando uso el método extern/dllexport mi función (como ejemplo) siempre es _test_func @ numbers mientras que el .def eliminó todos los cambios necesarios para usar con la aplicación que necesitaba exportar.

¿Podría alguien explicar por qué es esto? Solo tengo curiosidad sobre los dos métodos. ¡Gracias!

Respuesta

11

dllexport/import están diseñados para ser cargados por ellos mismos, no como una antigua biblioteca de C que usa GetProcAddress. El cambio que ha visto es lo que todos los compiladores de Microsoft han hecho durante mucho tiempo para __stdcall funciones. Lo más probable es que su objetivo o bien espera una función __cdecl, no __stdcall, pero si no, tendrá que usar un archivo .def para deshacer específicamente el nombre.

12

extern "C" no tiene nada que ver con stdcall: solo declara que C++ name mangling (también conocido como type-safe linkage; inclusión de información de tipo en el nombre del símbolo) está deshabilitado. Debe usarlo independientemente de si usa la convención de llamadas C o la convención de llamadas stdcall.

En la convención de llamadas stdcall, el destinatario elimina los parámetros de la pila. Para hacerlo seguro, el nombre exportado contiene la cantidad de bytes que el destinatario eliminará de la pila.

Si la aplicación que está exportando requiere que no se agregue el sufijo @number al nombre, probablemente signifique que espera la convención de llamadas de C. Por lo tanto, debe dejar de declarar la función como __stdcall. Cuando lo declare como declspec(dllexport), debe obtener un nombre no decorado en la DLL.

En el archivo DEF, puede llamar a la función como lo desee; no se realiza ninguna verificación adicional.

+15

windows api funciones son stdcall pero no tienen @number y en Windows es una práctica estándar hacerlo de esta manera. –