كيفية Marshal C ++ / CLI مجموعة من الهيكل إلى غير المدارة C ++

StackOverflow https://stackoverflow.com/questions/734996

سؤال

أنا أبحث عن بناء الجملة الصحيح لتمرير صفيف بنية إلى DLL C ++ غير المدارة.

تسمى واردات DLL الخاصة بي مثل هذا

    #define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);

في رمز عملائي لدي

List<MyStruct^> list;
MyObject::_Validation(/* list*/);

أنا أعرف النظام :: وقت التشغيل :: interopservices :: Marshal لديه الكثير من الأساليب المفيدة للقيام بالأشياء مثل هذا ولكن لست متأكدا من استخدامها.

هل كانت مفيدة؟

المحلول

قم بإنشاء إصدار مدار من الهيكل غير المدعوم باستخدام Instructlayout. مرسلته (تأكد من وضع الأمور بنفس الترتيب). يجب أن تكون قادرا بعد ذلك من اجتيازها كأنك تمر إلى أي وظيفة مدار (على سبيل المثال، التحقق من الصحة (m النص [] Persteds).

على سبيل المثال، دعنا نقول وظيفتنا الأصلية لها هذا النموذج الأولي:

extern "C" {

STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);

}

ويتم تعريف النتيجة الأصلية على النحو التالي:

struct MYSTRUCT
{
    int a;
    int b;
    char c;
};

ثم في C #، يمكنك تحديد إصدار مدار من الهيكل على النحو التالي:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MYSTRUCT
{
    public int a;
    public int b;
    public byte c;
}

والنموذج الأولي المدار كما يلي:

    [System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
    public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);

يمكنك بعد ذلك استدعاء الوظيفة التي تمر بمجموعة من هيكل النخيل على النحو التالي:

    static void Main(string[] args)
    {
        MYSTRUCT[] structs = new MYSTRUCT[5];

        for (int i = 0; i < structs.Length; i++)
        {
            structs[i].a = i;
            structs[i].b = i + structs.Length;
            structs[i].c = (byte)(60 + i);
        }

        NativeMethods.fnStructInteropTest(structs, structs.Length);

        Console.ReadLine();
    }

نصائح أخرى

يمكنك استخدام marshall.herenturetoptr. للحصول على INTPTR يمكن تمريرها إلى صفيف MeSuction الأصلي.

ومع ذلك، لست متأكدا من كيفية القيام بذلك من قائمة مباشرة. أعتقد أنك بحاجة إلى تحويل هذا إلى صفيف واستخدام PIN_PTR (لمنع GC من تحريك ذاكرتك) قبل تمريرها إلى الرمز الأصلي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top