2010-03-17 5 views
0

J'essaie d'appeler depuis 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:Impossible d'appeler l'entrée d'importation DLL, C# -> C++, EntryPointNotFoundException

Warning: CA1400 : Microsoft.Interoperability : Correct the declaration of 'SafeNativeMethods.SetHook()' so that it correctly points to an existing entry point in 'wi.dll'. The unmanaged entry point name currently linked to is SetHook.

Error: System.EntryPointNotFoundException was unhandled. Unable to find an entry point named 'SetHook' in DLL 'wi.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 tout le système de fichiers.

C++ définition de la fonction ressemble:

#define WI_API __declspec(dllexport) 
bool WI_API SetHook(); 

Je peux voir fonction exportée en utilisant Dependency Walker:

as decorated: bool SetHook(void) 
as undecorated: [email protected]@YA_NXZ 

C# importation DLL ressemble (je l'ai défini ces lignes en utilisant 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 EntryPoint et CallingConventio n définitions aussi bien.

Les deux projets sont de 32 bits, j'utilise W7 64 bits, VS 2010 RC.

Je crois que j'ai simplement oublié quelque chose ....

Merci à l'avance.

Répondre

4

Eh bien, vous connaissez le nom du point d'entrée, utilisez la propriété EntryPoint = "? SetHook @@ YA_NXZ" dans l'attribut [DllImport]. Ou mettez "C" externe avant la déclaration dans votre code C++ afin que le nom ne soit pas altéré.

[DllImport("wi.dll", EntryPoint = "[email protected]@YA_NXZ", CallingConvention = CallingConvention.Cdecl)] 
[return: MarshalAsAttribute(UnmanagedType.I1)] 
internal static extern bool SetHook(); 
+0

Parfait! Cela m'a aidé, j'ai mis extern "C" avant la déclaration. Merci beaucoup. – drumsta

+0

Mettez également __stdcall dans la déclaration, ce qui vous évite d'utiliser CallingConvention. –

1

CallingConvention.Cdecl C signifie 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 C++ nom décoration.

+0

merci pour l'explication !!! – drumsta

Questions connexes