No se puede llamar declaración de importación DLL, C # -> C ++, EntryPointNotFoundException
-
20-09-2019 - |
Pregunta
Estoy intentando llamar desde C # una función en un archivo DLL personalizado escrito en C ++. Sin embargo, yo estoy haciendo la advertencia durante el análisis del código y el error en tiempo de ejecución:
Advertencia: CA1400: Microsoft.Interoperability: Correcto la declaración de 'SafeNativeMethods.SetHook ()' de modo que correctamente apunta a una ya existente punto de entrada en 'wi.dll'. el no administrado Nombre del punto de entrada actualmente vinculado a es SetHook.
Error: System.EntryPointNotFoundException era no controlada. No es posible encontrar una entrada punto nombrado 'SetHook' en DLL 'wi.dll'.
Los dos proyectos wi.dll y C # exe ha sido compilada en la misma carpeta de depuración, los dos archivos residen aquí. Sólo hay un archivo con el nombre wi.dll en todo el sistema de archivos.
C ++ definición de función se ve así:
#define WI_API __declspec(dllexport)
bool WI_API SetHook();
puedo ver función exportada usando Dependency Walker:
as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ
C # importación DLL parece (he definido estas líneas usando CLRInsideOut de la revista MSDN):
[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
He intentado sin EntryPoint y CallingConvention definiciones también.
Ambos proyectos son de 32 bits, estoy usando W7 64 bits, VS 2010 RC.
Creo que simplemente me he pasado por alto algo ....
Gracias de antemano.
Solución
Bueno, ya sabes el nombre del punto de entrada, utilice el EntryPoint = "? SetHook @@ YA_NXZ" propiedad en el atributo [DllImport]. O dicho de extern "C" antes de la declaración en su código C ++ por lo que el nombre no que no se rompa.
[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
Otros consejos
CallingConvention.Cdecl
significa C no C ++, por lo que cuando se tiene una función con un nombre C ++ decorado, es necesario utilizar el nombre decorado como su EntryPoint
o utilizar extern "C" en la declaración de código C ++ para apagar C ++ decoración de nombres.