【问题标题】:Byte[].AsBuffer() copy results in Exception: Value does not fall within the expected rangeByte[].AsBuffer() 复制导致异常:值不在预期范围内
【发布时间】:2016-05-23 01:07:42
【问题描述】:

我正在尝试将 String 转换为 byte[],然后转换为 IBuffer 以设置我的 HidOutputReport.Data 字段。

当我尝试使用 byte[].AsBuffer() 时,VS2015 会抛出 ArgumentException 并提供“值不在预期范围内”作为有关异常的附加信息。

如果我尝试使用 DataWriter,当我调用 DataWriter.DetachBuffer() 时会引发相同的异常。

如果有人知道为什么会发生这种情况或我可以尝试将我的 String 放入 IBuffer 的替代方法,我们将不胜感激。

编辑:添加代码

HidOutputReport outputReport = device.CreateOutputReport();

byte[] bytesToCopy = new byte[textBox.Text.Length];
bytesToCopy = System.Text.Encoding.ASCII.GetBytes(textBox.Text);

//DataWriter dataWriter = new DataWriter();
//dataWriter.WriteBytes(bytesToCopy);

outputReport.Data = bytesToCopy.AsBuffer();
//outputReport.Data = CryptographicBuffer.CreateFromByteArray(bytesToCopy);

//WindowsRuntimeBufferExtensions.CopyTo(bytesToCopy, 0, outputReport.Data, 0, bytesToCopy.Length);
uint bytesWritten = await proscannerSystem_device.SendOutputReportAsync(outputReport);

您可以看到我尝试复制的其他一些方法。值得注意的是WindowsRuntimeBufferExtensions.CopyTo() 似乎 可以工作,但是我错过了第一个字节(我试图弄清楚这是否是我的副本的问题,并让我遇到了这个问题倾向于相信它是)。

【问题讨论】:

  • 你可以用你的代码更新你的问题吗?
  • 嘿@RogerHartley 我已经添加了一些代码,但我不相信它会提供很多洞察力。
  • 我想知道编码是否可能是问题 - 您使用的是 ASCII 编码,但字符串是 UT16。我不相信这是答案,因为 AsBuffer() 只是将 IBuffer 包装在一堆字节上,它并不关心这些字节是什么。但是,这是可以尝试的——尝试使用 Encoding.Unicode.GetBytes() 看看它是否有任何不同。

标签: c# usb windows-10 win-universal-app hid


【解决方案1】:

首先,要了解问题所在,在发生异常的地方换行。

HidOutputReport outputReport = device.CreateOutputReport();

byte[] bytesToCopy = new byte[textBox.Text.Length];
bytesToCopy = System.Text.Encoding.ASCII.GetBytes(textBox.Text);

//I used a similiar one (equals the customHID sample)
//DataWriter dataWriter = new DataWriter();
//dataWriter.WriteBytes(bytesToCopy);

// This line is to show for you that the problem isn't the bytesToCopy but the your filling vector (Value does not fall within the expected range).
var x=bytesToCopy.AsBuffer();

//Here, You take the bytes and put in report data. If outputReport.Data.Capacity was different of your bytesToCopy.Length the app throws a exception.*
outputReport.Data = x;

//outputReport.Data = CryptographicBuffer.CreateFromByteArray(bytesToCopy);

//WindowsRuntimeBufferExtensions.CopyTo(bytesToCopy, 0, outputReport.Data, 0, bytesToCopy.Length);
uint bytesWritten = await proscannerSystem_device.SendOutputReportAsync(outputReport);

*我在反汇编列表中检查,当程序比较与您的 bytesToCopy 类似的 outputreport 和 dataWriter.DetachBuffer() 之间的容量和长度时,会出现问题。

要解决问题,请确保两者相等,如果不相等,则填充向量或抛出异常以了解问题所在。

 var x = bytesToCopy.AsBuffer();

if(outputReport.Data.Capacity != x.Length)
{ throw new Exception("Buffer didn't work. Correct the ranger filling the vector x"); 
else{
outputReport.Data=x;
}

在我的情况下,我做到了......

DataWriter dataWriter = new DataWriter();
dataWriter.WriteByte(outputreport.Id);
dataWriter.WriteString(bytes_vector);
//IBuffer is 1(WriteByte) + bytes_vector.length

//in my case the capacity is 65 => fill bytes_vector to 65
for(int i=(bytes_vector.Length+1);i<outputReport.Data.Capacity;i++)         
{
 dataWriter.WriteByte((Byte)0);
}

var x = dataWriter.DetachBuffer();
outputReport.Data=x;

}

别忘了第一个位置是 outputreport.Id。

问候

吉尔赫姆·马克斯

【讨论】:

    【解决方案2】:

    将 outputreport.Data 的长度与要复制的字节进行比较。 outputreport.data 中的第一个字节表示您请求的报告类型。尝试在 bytestoCopy 中将第一个字节设置为 0,并在使用 AsBuffer() 之前将文本框内容添加为字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      相关资源
      最近更新 更多