2009-09-23 21 views
25

Estoy tratando de crear una DLL que exporte una función llamada "GetName". Me gustaría que otro código pueda llamar a esta función sin tener que conocer el nombre de la función destruida.¿Cómo puedo detener el cambio de nombre de la función exportada de mi DLL?

Mi archivo de cabecera tiene el siguiente aspecto:

#ifdef __cplusplus 
#define EXPORT extern "C" __declspec (dllexport) 
#else 
#define EXPORT __declspec (dllexport) 
#endif 

EXPORT TCHAR * CALLBACK GetName(); 

Mi código es el siguiente:

#include <windows.h> 
#include "PluginOne.h" 

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) 
{ 
    return TRUE ; 
} 

EXPORT TCHAR * CALLBACK GetName() 
{ 
    return TEXT("Test Name"); 
} 

Cuando construyo, la DLL aún exporta la función con el nombre: "_GetName @ 0" .

¿Qué estoy haciendo mal?

Respuesta

21

pequeña corrección - para el éxito resolviendo nombre por clinet

extern "C" 

debe ser lo más en el lado de la exportación como en la importación.

extern "C" reducirá el nombre de proc a: "_GetName".

Más encima se puede obligar a ningún nombre con ayuda de la sección de las exportaciones en el archivo .def

+0

Hey fresco esto es exactamente lo que necesito casi. ¿Y ahora si lo quiero al revés? Tengo la función C, está completamente bien para ser la función miembro de C++ (vtable, llamando a la convención todo hecho), pero el compilador cree que su nombre debe ser mutilado. – Pyjong

+0

Sí, C y C++ usan reglas de decoración de nombres diferentes. Para hacer lo que pregunta, debe crear un contenedor que invoca la función C del miembro de la clase C++ – Dewfy

+0

Un archivo .DEF es la única forma de desactivar el cambio de nombre. 'extern" C "' todavía usará decoración de nombre, pero no tan detallado como lo necesita C++. – IInspectable

9

Esto es normal para una exportación DLL con una convención __stdcall. El @Nindicates the number of bytes that the function takes in its arguments - en su caso, cero.

Tenga en cuenta que the MSDN page on Exporting from a DLL dice específicamente "utilizar la convención de llamadas __stdcall" cuando se usa "la palabra clave __declspec (dllexport) en la definición de la función".

+1

Como se menciona [aquí] (http://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names), la única forma de superar el cambio de '' __stdcall' es usar: '#pragma comment (linker,"/EXPORT: SomeFunction = _SomeFunction @@@ 23mangledstuff # @@@@ ")' – Pierre

+0

su primer enlace está roto y el segundo apunta a una descarga –

4

la respuesta correcta es la siguiente:

extern "C" int MyFunc(int param); 

y

int MyFunc(int param); 

es dos declaraciones que utiliza diferentes nombres interno, primero - se encuentra en C estilo, segundo, en el estilo C++.

naming interno requerido para las herramientas de compilación para determinar qué argumentos recibe la función, qué tipo devuelve, etc. ya que C++ es más complicado (oop, sobrecargado, funciones virtuales, etc.) - usa nombres más complicados. la convención de llamadas también afecta los nombres c y C++.

Ambos estilos de nomenclatura se aplican cuando se utiliza __declspec (dllexport) de la misma manera.

si desea omitir renombrado de nombres de la rutina exportada, añadir un archivo de definición de módulo a su proyecto, escriba en ella (en este caso no se requiere que declspec dllexport):

LIBRARY mylib 
EXPORTS 
    MyFunc 

este omitirá explícita decoración del nombre (ejemplos a continuación).

_MyFunc (c style, __cdecl) 
[email protected] (c style, __stdcall) 
[email protected]@[email protected] (c++ style, __cdecl) 
[email protected]@[email protected] (c++ style, __stdcall) 
0

Puede usar el interruptor de enlace "-Wl, - kill-at" para desactivar el cambio de nombre.

Por ejemplo, en el Code :: Blocks, en los ajustes de engarce personalizados, añadir: -Wl, - matar-a

Cuestiones relacionadas