【问题标题】:Can I pass subset of an array to function in VB.NET?我可以将数组的子集传递给 VB.NET 中的函数吗?
【发布时间】:2010-06-25 16:43:54
【问题描述】:

我有一个简单的 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 将保存从source_id 开始的值number_of_values 的长列表,从first_value_address 开始。

有一个硬件驱动的限制,即无论请求的长度如何,返回的值的最大数量为 15。我需要从我的 VB.NET 代码中获取 28 个值到一个数组中。

是否可以只将数组变量的一部分发送到类似于以下 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

【问题讨论】:

    标签: vb.net arrays pass-by-reference


    【解决方案1】:

    不,您的具体要求是不可能的。与 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;
    }
    

    还要注意ByValByRef代表调用约定,而不是类型是否是值类型。除非您有特定的理由(这里似乎没有),否则您不需要在数组参数上指定 ByRef。唯一需要 ByRef 的类型是函数将更改变量的实际值并且您希望将其反映在调用代码中。您调用它的方式似乎是分配数组,将其传递给函数,然后使用其内容。该函数唯一一次修改变量的值是如果它设置它等于一个不同的数组实例;只需更改数组值不需要ByRef 即可让调用代码看到结果。

    **除非您实际使用 unsafe 代码并自己执行基于指针的数组,但这超出了您的问题范围*

    【讨论】:

    • ByRef 是库函数的产物。真的是一个C#输出参数
    • @CSharperWithJava:实际上,out 是 C# 特有的功能。 IL 本身没有out 的概念,只有ref。 C# 仅验证您的函数在所有返回路径中为变量分配值的编译时。除此之外,这个答案应该是正确的。
    【解决方案2】:

    据我所知,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
    

    【讨论】:

    • 我认为您可以在数组上调用ToList(),而不是创建一个列表并使用AddRange() 将值复制到其中。
    【解决方案3】:

    您必须创建一个固定大小的缓冲区数组并将其放入您的函数中。然后复制到main,可以任意大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2017-04-17
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多