Могу ли я передать подмножество массива для работы в VB.NET? - PullRequest
2 голосов
/ 25 июня 2010

У меня есть простая форма VB.NET, которая действует как интерфейс к библиотеке управления с общедоступным API.

Один из вызовов API принимает массив UIntegers ByRef:

Public Function Get_Values(source_id As Byte, first_value_address As Byte, number_of_values As Byte, ByRef valuesOut As UInteger()) As Integer

После вызова valuesOut будет содержать список значений number_of_values длиной от source_id, начиная с first_value_address.

Существует аппаратное ограничение, согласно которому максимальное количество возвращаемых значений равно 15, независимо от запрашиваемой длины. Мне нужно получить 28 значений в массив из моего кода VB.NET.

Возможно ли отправить только часть переменной массива в функцию, подобную следующей C-код?

uint[28] values;
Get_Values(0, 0, 15, values); // Get first part
Get_Values(0, 15, 13, &values[15]); // Get second part of data

Ответы [ 3 ]

2 голосов
/ 25 июня 2010

Нет, то, что вы конкретно просите, невозможно. В отличие от массивов в стиле C / C ++ (упрощенно - это просто блоки памяти, равные sizeof(Type) * n, где n - количество элементов), массивы .NET не могут ссылаться или смещаться арифметикой указателей *. В результате, если общедоступный API не предоставит вам способ указать смещение в массиве, вам придется передать промежуточные массивы в функцию и собрать их самостоятельно, как только вы закончите.

Однако вы можете заключить вызов в собственную версию функции:

public int GetValues(byte source_id, byte first_value_address, byte number_of_values, uint[] buffer, int offset)
{
    uint[] temp = new uint[number_of_values];

    int retValue = GetValues(source_id, first_value_address, number_of_values, temp);

    Array.Copy(temp, 0, buffer, offset, number_of_values);

    return retValue;
}

Следует также отметить, что ByVal и ByRef представляют соглашения о вызовах, независимо от того, является ли тип типом значения. Если у вас нет конкретной причины (а здесь, похоже, у вас ее нет), вам не нужно указывать ByRef в аргументе массива. Единственный тип ByRef требуется, когда функция изменит фактическое значение переменной, и вы хотите, чтобы это отражалось в вызывающем коде. То, как вы его вызываете, похоже, что вы выделяете массив, передаете его функции, а затем используете его содержимое. Единственный раз, когда функция изменяет значение переменной, это если она установлена ​​равной другой экземпляр массива ; простое изменение значений массива не требует ByRef, чтобы вызывающий код мог видеть результаты.

** Если вы на самом деле не используете код unsafe и не делаете массивы на основе указателей самостоятельно, но это выходит за рамки вашего вопроса *

0 голосов
/ 25 июня 2010

Насколько я знаю, одни массивы не имеют такой возможности в VB.Хотя я могу ошибаться, я сам новичок в VB - обходной путь - преобразовать массив в список (так как ваш массив выглядит довольно маленьким, это не должно быть проблемой), вызовите процедуру addRange,затем метод toArray ().

 Dim list as New List(Of Object)
 list.addRange(theArray)
 theArray = list.GetRange(0, 2).ToArray() ' Gets only the first two indices and puts them into an array
0 голосов
/ 25 июня 2010

Вы должны создать буферный массив фиксированного размера и поместить его в свою функцию. Затем скопируйте на главную, которая может быть любого размера.

...