Impossible d'appeler l'entrée d'importation DLL, C # -> C ++, EntryPointNotFoundException
-
20-09-2019 - |
Question
Je suis en train d'appeler à partir de C # une fonction dans une DLL personnalisée écrite en C ++. Cependant, je reçois l'avertissement lors de l'analyse de code et l'erreur lors de l'exécution:
Attention: CA1400: Microsoft.Interoperability: Correct la déclaration de 'SafeNativeMethods.SetHook ()' de telle sorte que il souligne à juste titre à un existant point d'entrée 'wi.dll'. le non géré Nom du point d'entrée actuellement liée à est SetHook.
Erreur: System.EntryPointNotFoundException était non prise en charge. Impossible de trouver une entrée le point nommé 'SetHook' dans 'wi.dll' DLL.
Les deux projets wi.dll et C # exe a été compilé dans le même dossier DEBUG, les deux fichiers se trouvent ici. Il n'y a qu'un seul fichier avec le nom wi.dll dans l'ensemble du système de fichiers.
C ++ définition de la fonction ressemble à:
#define WI_API __declspec(dllexport)
bool WI_API SetHook();
Je peux voir la fonction exportée en utilisant Dependency Walker:
as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ
C # importation DLL ressemble (je l'ai défini ces lignes à l'aide CLRInsideOut du magazine MSDN):
[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
J'ai essayé sans définitions et Entrypoint CallingConvention ainsi.
Les deux projets sont 32 bits, j'utilise W7 64 bits, VS 2010 RC.
Je crois que je l'ai simplement oublié quelque chose ....
Merci d'avance.
La solution
Eh bien, vous savez le nom du point d'entrée, utilisez la propriété EntryPoint = "SetHook @@ YA_NXZ" dans l'attribut [DllImport]. Ou mettre extern « C » avant la déclaration dans votre code C ++ de sorte que le nom ne soit pas mutilée.
[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
Autres conseils
CallingConvention.Cdecl
signifie C pas C ++, donc quand vous avez une fonction avec un nom décoré C ++, vous devez utiliser le nom décoré comme EntryPoint
ou utiliser extern « C » dans la déclaration de code C ++ pour désactiver la décoration de nom C ++.