Как маршалировать массив структуры C'/CLI на неуправляемый C

Я ищу правильный синтаксис для передачи структурного массива в неуправляемый C'dll.

мой dll импорта называются, как это

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

В моем клиентском коде у меня есть

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

Я знаю, система::Runtime::InteropServices::Marshal имеет много полезных методов для делать вещи, как это, но я не уверен, какие использовать.

Ответ на: "Как маршалировать массив структуры C'/CLI на неуправляемый C"

Количество ответов:2

Вы можете использовать Marshall.StructureToPtr to get an IntPtr which could be passed into a native MyStruct* array. для получения IntPtr, который может быть передан в родной массив MyStruct.

Однако, я не знаю, как это сделать из списка непосредственно. Я считаю, что вам нужно преобразовать это в массив и использовать pin_ptr (чтобы предотвратить GC от перемещения памяти) до передачи его на родной код.

Создайте управляемую версию неуправляемой структуры с помощью StructLayout.Sequential (не забудьте поставить вещи в том же порядке). Затем вы должны быть в состоянии передать его, как вы бы передать его на любую управляемую функцию (например, проверка (MyStruct' pStructs).

Например, Скажем, наша родная функция имеет этот прототип:

extern "C" {

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

}

и родной MYSTRUCT определяется следующим образом:

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);

Вы можете тогда назвать функцию, передающая его массиву СТРУКТУРы 22s следующим образом:

    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();
    }