لا يمكن استدعاء إدخال استيراد DLL ، C# -> C ++ ، EntplointNotFoundException
-
20-09-2019 - |
سؤال
أحاول الاتصال من C# وظيفة في DLL مخصصة مكتوبة في C ++. ومع ذلك ، أحصل على التحذير أثناء تحليل التعليمات البرمجية والخطأ في وقت التشغيل:
تحذير: CA1400: Microsoft.Interportability: تصحيح إعلان "SafenativeMethods.Sethook ()" بحيث يشير بشكل صحيح إلى نقطة دخول موجودة في "Wi.dll". اسم نقطة الدخول غير المدير المرتبط حاليًا هو Sethook.
خطأ: System.EntryPointNotfoundException لم يتم تحديده. غير قادر على العثور على نقطة دخول تسمى "Sethook" في DLL "Wi.dll".
تم تجميع كلا المشروعين wi.dll و c# exe في مجلد التصحيح نفسه ، كلا الملفان يقيمان هنا. لا يوجد سوى ملف واحد يحمل اسم Wi.dll في نظام الملفات بأكمله.
يشبه تعريف وظيفة C ++:
#define WI_API __declspec(dllexport)
bool WI_API SetHook();
أستطيع أن أرى الوظيفة المصدرة باستخدام Walker التبعية:
as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ
يشبه الاستيراد C# DLL (لقد حددت هذه الخطوط باستخدام Clrinsideout من مجلة MSDN):
[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
لقد حاولت دون دخول واتصالات CallConvention أيضًا.
كلا المشروعين 32 بت ، أنا أستخدم W7 64 بت ، مقابل 2010 RC.
أعتقد أنني ببساطة أغفلت شيئًا ....
شكرا لك مقدما.
المحلول
حسنًا ، أنت تعرف اسم نقطة الإدخال ، استخدم خاصية Entploint = "؟ sethook ya_nxz" في سمة [dllimport]. أو ضع EXTERN "C" قبل الإعلان في رمز C ++ الخاص بك حتى لا يتم تشويه الاسم.
[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
نصائح أخرى
CallingConvention.Cdecl
يعني C ليس C ++ ، لذلك عندما يكون لديك وظيفة مع اسم مزخرف C ++ ، تحتاج إلى استخدام الاسم المزين كما هو الخاص بك EntryPoint
أو استخدم Extern "C" في إعلان رمز C ++ لإيقاف تشغيل Decoration C ++.