Converting a number larger than 255 into a byte variable - vb.net

I understand the concept of bytes and declaring variables to save on processing space. I understand that the max value that can be stored in a byte is 255.
I cannot seem to wrap my head around my current issue and was hoping that someone would be able to educate me and help me solve this problem. I don't have much experience working with byte manipulation.
I was given a project to update and was told that the service that is passing data to my project would start using 2bytes to transfer the ID rather than the 1 byte previously as their parameters have grown.
The current declaration for the variable is:
Dim bytvariable As Byte = 0
What is the new declaration to accept a 2 byte value?
Secondly, how would I be able to convert that 2 byte value into an integer number?
Example, they are passing me this value: 0x138 and it is supposed to come out as 312.
Thank you in advance.

Here's a summary of the "primitive" datatypes in .NET, and their sizes.
Yes, an Int16 is probably what you want.
Often you'd be reading the binary data from a stream, or getting it from an array of bytes.
To convert from those sources into an Int16, you can do this:
in C#:
byte[] block = new byte[128];
mystream.Read(block, 0, block.Length);
int i = 0;
Int16 value = (Int16)(block[i++] + block[i++] * 256);
In VB.NET, it would be:
Dim block as New Byte(128)
stream.Read(block, 0, block.Length)
Dim i as Int16 = 0
Dim value As Short = CShort((block(i) + (buffer(i+1) * &H100)))
i = i + 2
(I think)

from the top of my head I'd suggest if you insist on doing it that way (instead of just passing an integer), you could use an array of byte, first index holding the first number and the second index the second ex. byte[0] = 123, byte[1] = 255;
then combine them into a string ex. string concatenatedNumber = byte[0].ToString() + byte[1].ToString(); then parse it ex. int ID = Int32.Parse(concatenatedNumber);
Examples are in C#, but I think you should get the idea. I would definitely rather just pass it as an integer though.

You could try this:
Dim bytvariable As Byte(0 To 1)
bytvariable(0) = ' Get the first byte however they are sending it
bytvariable(1) = ' Get the second byte however they are sending it
Dim value As Int16 = BitConverter.ToInt16(buffer, 0);

Related

Fail at sending byte array through serial port excel-vba

I am trying to get information from an Excel worksheet and send it through a serial port as a byte array, using Windows API. This is just a small part of it:
lngSize = UBound(byteData) - LBound(byteData)
WriteFile(udtPorts(intPortID).lngHandle, byteData, lngSize, _lngWrSize, udtCommOverlap)
My current problem: when I am sending a byte array of length 1 (just one byte), I receive it correctly (I am using a hyperterminal to check what I'm sending), but when I send an array of length > 1, here comes the problem; instead of receiving it like this:
letter = 65
For i = 0 To 5
dataToSend(i) = letter
letter = letter + 1
Next
what I should receive
what I get is this:
what I receive
I really cannot figure out what could be the problem and I would be grateful if someone had a clue. Thank you!
First, the correct number of elements in an array is:
lngSize = UBound(byteData) - LBound(byteData) + 1 ' <-- add 1
More importantly, your code is not applying the call convention for the WriteFile API. Namely, the second parameter should be a LPCVOID pointer to the first Byte to transfer. Passing the array's name byteData to the function wont achieve that, because the array is a complex COM data structure, not like a C array. What you should do is:
First get the address of the array's data structure, using VarPtrArray:
Then add 12 to it to get the address of the first byte.
.
Private Declare Function VarPtrArray Lib "VBE7" Alias "VarPtr" (var () As Any) As Long
...
WriteFile(udtPorts(intPortID).lngHandle, VarPtrArray(byteData()) + 12, lngSize, _lngWrSize, udtCommOverlap)
' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For information about handling arrays' data and their pointers, excellent examples can be found [on this page].(https://www.codeproject.com/Articles/729235/VB-and-VBA-Array-Buffering)
Also make sure that you declared you array as a Byte array, like
Redim byteData(someSize) As Byte
' ^^^^^^^
There might be other errors in the parts of code you didn't show (possibly the settings of udtCommOverlap), but hopefully these corrections will put you on the right track.

Using plus equals operator with bytes

The code below gives me the following error.
Error: Type mismatch: inferred type is kotlin.Int but kotlin.Byte was expected
var temp: Byte = 0
var temp2: Byte = 1
temp += temp2
Is there any way around this in kotlin or am I not allowed to use the += or -= operators with Byte? Is plus equals overloaded for Long and Int but not Byte and Short?
According to kotlin docs Byte's plus/minus operations with other Byte will result in an Int. So while you think it is weird try to add Byte with value of 255 to other Byte with calue of 255 ;)
I think they made it on purpose. If you are certain that your result is still within Byte bounds then just use Int.toByte() and the end of the calculations.

Convert audio doubles to bytes

I am dealing with raw PCM audio data (the audio data of a PCM file without the header).
This data is provided to me in the form of a vector of double.
I would like to pass this data to another function, and this function expects the audio data in the form of a byte vector.
I tried
Dim nBytes() As Byte = nDoubles.SelectMany(Function(d) BitConverter.GetBytes(d)).ToArray()
but that wouldn't give the expected results.
I guess I have to deal with the conversion manually, but I am unsure how this should be done.
Can anybody help?
Thank you.
Since the required format for the other function is 16-bit, 48 kHz, which is the same as your source data, it's a simple case of converting the source to an array of Short, then serializing this as a Byte array.
The problem with the code you suggest for this is that the first step is missed, so it basically serializes the Double array. However, you can re-use this for the second step. So, you can do something like:
Dim nShorts() As Short = New Short(nDoubles.Length - 1) {}
For i = 0 To nDoubles.Length - 1
nShorts(i) = Convert.ToInt16(nDoubles(i))
Next
Dim nBytes() As Byte = nShorts.SelectMany(Function(s) BitConverter.GetBytes(s)).ToArray()

Objective C - NSNumber storing and retrieving longLongValue always prefixes with 0xFFFFFFFF

I am trying to store a file size in bytes as an NSNumber. I am reading the file download size from the NSURLResponse and that gives me a long long value and I then create an NSNumber object from that value and store it. When I go to retrieve that value later, it comes back with all the higher bytes set as FFFFFFFF.
For example, I read in the size as 2196772870 bytes (0x82f01806) and then store it into the NSNumber. When I get it back, I get -2098194426 bytes (0xffffffff82f01806). I tried doing a binary AND with 0x00000000FFFFFFFF before storing the value in NSNumber but it still comes back as negative. Code below:
long long bytesTotal = response.expectedContentLength;
NSLog(#"bytesTotal = %llx",bytesTotal);
[downloadInfo setFileTotalSize:[NSNumber numberWithInt:bytesTotal]];
//[downloadInfo setFileTotalSize:[NSNumber numberWithLongLong:bytesTotal]];
long long fileTotalSize = [[downloadInfo fileTotalSize] longLongValue];
NSLog(#"fileTotalSize = %llx",fileTotalSize);
Output:
bytesTotal = 82f01806
fileTotalSize = ffffffff82f01806
Any suggestions?
Edit: Completely forgot the setter for the downloadInfo object.
The problem is this line:
[downloadInfo setFileTotalSize:[NSNumber numberWithInt:bytesTotal]];
bytesTotal is not an int, it's a long long, so you should be using numberWithLongLong:, not numberWithInt:. Change it to:
[downloadInfo setFileTotalSize:[NSNumber numberWithLongLong:bytesTotal]];
The conversion is causing it to be sign extended to 64 bits, and the number starting with 8 appears to be a negative number so that bit gets extended all the way thru the upper long, causing it to be ffffffff.

How do I limit BitConverter.GetBytes() to return only a certain amount of bytes using VB.NET?

I do:
Dim BytArr() as Byte = BitConverter.GetBytes(1234)
Since, by default, they are 32 bits, it returns 4 byte elements.
I want to be able to control it to return only like two bytes. Maybe only three bytes. Are there any built-in functions to control it?
I don't want to rely on using shifting >> 8 >> 16 >> 24 >> 32, etc..
I also don't want to rely on type casting the data in GetBytes() to a specific datatype.
It is not that GetBytes defaults to 32 bits, it is that GetBytes returns an array of the size required to hold the data type. If you pass a Long then you will get a 8 elements in your array.
The best way to control this is indeed casting the data you pass in. Otherwise you could truncate some of the number.
That being said, you could do something like this:
Dim BytArr() as Byte = Array.Resize(BitConverter.GetBytes(1234), 2)
But if the value you passed in exceeded what could be stored in 2 bytes (in this case) then you will have some very broken code.