Как мне получить следующий элемент в массиве, когда я получаю первый элемент через pinvoke?

Я использую API, метод которого определен следующим образом:

[DllImport("icsneo40.dll")]
public static extern Int32 icsneoGetMessages(Int32 hObject, ref icsSpyMessage pMsg, ref          Int32 pNumberOfMessages, ref Int32 pNumberOfErrors);

с параметром icsSpyMessage, описанным как:

pMsg [out]
Это адрес первого элемента массива структур icsSpyMessage. Этот массив будет загружен сообщениями, полученными оборудованием. Размер этого массива должен соответствовать 20 000 структур icsSpyMessage.

Мой вопрос: как мне получить доступ к другим элементам в массиве, когда все, что у меня есть, это первый элемент?


person scott    schedule 26.01.2012    source источник


Ответы (3)


Поскольку вы передаете массив, вы должны объявить icsSpyMessage массивом:

[DllImport("icsneo40.dll")]
public static extern Int32 icsneoGetMessages(
    Int32 hObject, 
    [Out] icsSpyMessage[] pMsg,
    ref Int32 pNumberOfMessages, 
    ref Int32 pNumberOfErrors
);

Атрибут [out] указывает маршаллеру p/invoke маршалировать собственную память обратно в ваш управляемый массив структур. Маршаллер будет маршалировать элементы в соответствии с длиной управляемого массива.

Поэтому вам нужно выделить этот массив перед вызовом функции. API, который вы вызываете, требует, чтобы вы предоставили массив из не менее 20 000 элементов.

icsSpyMessage[] pMsg = new icsSpyMessage[20000];
Int32 result = icsneoGetMessages(hObject, pMsg, 
    ref pNumberOfMessages, ref pNumberOfErrors);
person David Heffernan    schedule 26.01.2012

Так:

[DllImport("icsneo40.dll")]

public static extern Int32 icsneoGetMessages(
    Int32 hObject, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
    out icsSpyMessage[] pMsg, 
    ref Int32 pNumberOfMessages, 
    ref Int32 pNumberOfErrors
);
person Ben    schedule 26.01.2012
comment
Это неправильно. Он не должен использовать параметр out. Это должно быть удалено. Вместо этого вам нужен атрибут [out]. Смотрите мой ответ. И, как оказалось, нет необходимости в MarshalAs, так как поведение по умолчанию заключается в маршалировании всего массива. Я предполагаю, что SizeParamIndex может быть ценным из соображений производительности. - person David Heffernan; 26.01.2012

Зачем все усложнять? Все это указатель, указывающий на какую-то структуру или массив структур. Поэтому объявите свой массив размером 20k

icsSpyMessage мои сообщения [20000];

передайте его этому методу следующим образом:

int result = icsneoGetMessages( blahh, myMessages[0], // ‹‹== это указатель на первый элемент структуры или объекта... blahh, blahh);

Когда вы получаете сообщения, вы можете выполнить итерацию через «foreach (элемент icsSpyMessage в myMessages) { ... }

надеюсь это поможет..

person Leo928    schedule 10.01.2013