مكتبة C # DllImport مكتوبة على C ++

أنا جديدة في C #. لدي دلل مكتوب على C ++ من نفسي ، وأنا ذاهب لاستخدام وظائف من هذا DLL في C# التطبيق.

لذلك ، أفعل ما يلي عند الإعلان عن الوظائف في مشروع C ++:

public static __declspec(dllexport) int captureCamera(int& captureId);

ثم أحاول استيراد هذه الطريقة في تطبيق C #:

[DllImport("MyLib.dll")]
public static extern int captureCamera(ref int captureId);

لكن لدي استثناء:

Unable to find an entry point named 'captureCamera' in DLL 'MyLib.dll'.

المهمة هي القيام dllimport دون تحديد معلمة EntryPoint. يمكن أي واحد يساعدني؟

0
تم التغيير من public static إلى public: static - لم يتغير شيء.
وأضاف المؤلف Max Myasoed, مصدر
يجب تحديد منفذ الإدخال داخل رمز C #.
وأضاف المؤلف Security Hound, مصدر
public static تشير إلى أن وظيفتك داخل فئة C ++. يمكن لـ C# الوصول إلى وظائف C فقط. الى جانب ذلك، بناء الجملة غير صحيح (كان ينبغي أن يكون <�كود> الجمهور: ثابت </القانون>). لذلك هذا على ما يبدو ليس تصريح وظيفتك الحقيقية.
وأضاف المؤلف dialer, مصدر

3 إجابة

public static __declspec(dllexport) int captureCamera(int& captureId);

هل هذه الطريقة؟ إذا كانت وظيفة ، فإنها لا يمكن أن تكون ثابتة ، حيث أن ثابت و dllexport متبادلان.

والاسم هو مشوهة. راجع http://en.wikipedia.org/wiki/Microsoft_Visual_C٪2B٪2B_Name_Mangling. إذا كان يمكنك الحصول على الاسم المتشابك ، ثم قدم DllImport معه ( EntryPoint = MANGLED_NAME ) ، فيجب أن يعمل.

يمكنك توفير رابط بالملف .def ، يحتوي على تعريف للوظائف المصدرة ، ولا يتم تغيير أسمائها بعد ذلك:

Project.def:

EXPORTS
    captureCamera @1
4
وأضاف
المهمة هي القيام dllimport دون تحديد معلمة EntryPoint. لقد نسيت أن أذكر هذا الشرط.
وأضاف المؤلف Max Myasoed, مصدر

تقوم بتعريف دالة C ++ بدون كتلة "C" خارجية. كما يسمح لك C ++ للوظائف الزائدة (بمعنى إنشاء العديد من الدالات captCamera() مع مجموعات مختلفة من الوسائط) ، سيكون اسم الدالة الفعلي داخل DLL مختلفًا. يمكنك التحقق من ذلك عن طريق فتح موجه الأوامر Visual Studio ، والانتقال إلى الدليل الثنائي الخاص بك وتشغيل هذا:

dumpbin /exports YourDll.dll

سوف تحصل على شيء من هذا القبيل:

Dump of file debug\dll1.dll

File Type: DLL

  Section contains the following exports for dll1.dll

    00000000 characteristics
    4FE8581B time date stamp Mon Jun 25 14:22:51 2012
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00011087 [email protected]@[email protected] = @ILT+130([email protected]@[email protected])

  Summary

        1000 .data
        1000 .idata
        2000 .rdata
        1000 .reloc
        1000 .rsrc
        4000 .text
       10000 .textbss

إن ؟ captureCameraYAHAAH @ Z هو الاسم المتشابك الذي يشفر فعليًا الحجج التي حددتها.

كما ذكر في إجابات أخرى ، ببساطة إضافة extern "C" إلى الإعلان الخاص بك:

extern "C" __declspec(dllexport) int captureCamera(int& captureId)
{
    ...
}

يمكنك إعادة التحقق من صحة الاسم عن طريق إعادة تشغيل dumpbin:

Dump of file debug\dll1.dll

File Type: DLL

  Section contains the following exports for dll1.dll

    00000000 characteristics
    4FE858FC time date stamp Mon Jun 25 14:26:36 2012
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000110B4 captureCamera = @ILT+175(_captureCamera)

  Summary

        1000 .data
        1000 .idata
        2000 .rdata
        1000 .reloc
        1000 .rsrc
        4000 .text
       10000 .textbss
3
وأضاف

هل أنت تعلن

extern "C" {
    __declspec(dllexport) int captureCamera(int& captureId);
}

داخل c ++ code - C# يمكن فقط الوصول إلى C ، وليس C ++.

2
وأضاف
نعم ، لدي هذا الإعلان في كود C ++ الخاص بي.
وأضاف المؤلف Max Myasoed, مصدر