VB6 to VB.NET CopyMemory - vb.net

Hey all I am trying to convert a little bit of VB6 to .NET and I am getting the error of:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string " " to type 'Integer' is not valid.
The following .net code is where its getting stuck at CopyMemory(str_Renamed, ptr, count):
Public Function ptrToStr(ByVal ptr As Integer) As String
Dim count As Integer
Dim str_Renamed As String
count = lstrlen(ptr)
If count Then
str_Renamed = New String(vbNullChar, count)
CopyMemory(str_Renamed, ptr, count)
ptrToStr = str_Renamed
Else
ptrToStr = ""
End If
End Function
The values for those varibles are:
count = 4
ptr = 268978536
str_Renamed = " "
I'm not sure how to go about fixing this error...

The problem looks to be that you are passing a string as the first parameter of the CopyMemory function. The CopyMemory function expects a pointer as the first parameter so the code is attempting to convert the string parameter to an integer. As far as I am aware, the only valid values for pointers are either integer values or hex values.

Related

system.invalidcastexception 'conversion from string to type 'double' is not valid.' vb.net

system.invalidcastexception 'conversion from string to type 'double' is not valid.
' vb.net
receiptDetails = lstReceipt.SelectedItem
Dim newTotalAmount As Double = CDbl(receiptDetails.Remove(0, 94))
lstReceipt.Items.RemoveAt(lstReceipt.SelectedIndex)
totalAmount -= newTotalAmount
txtTotal.Text = totalAmount.ToString("GH₵###,###.00")
txtDiscount.Text = discountAmount.ToString("GH₵###,###.00")
txtTaxableAmount.Text = TaxableAmount.ToString("GH₵###,###.00")
txtVat.Text = taxAmount.ToString("GH₵###,###.00")
txtPayableAmount.Text = payableAmount.ToString("GH₵###,###.00")
End Sub
If I had to guess, the code is failing at:
Dim newTotalAmount As Double = CDbl(receiptDetails.Remove(0, 94))
I suggest using TryParse instead of CDbl to verify that the value can be converted to a Double. If the result of TryParse is False, then display the value that attempted to be converted:
Dim massagedValue As String = receiptDetails.Remove(0, 94)
Dim newTotalAmount As Double
If (Double.TryParse(massagedValue, newTotalAmount)) Then
' continue business logic ...
Else
MessageBox.Show($"The following value is not a valid double: {massagedValue}", "Invalid Double", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Now when you get the user-friendly error message you can determine why the value is not able to be converted to a double.
My best guess is that you are not removing enough or are removing too much characters from the receiptDetails variable.

Why do I get an overflow when doing a logical AND

Am using VS2010 VB.net
Dim Register As UInt64
Register = 12297264199100303880
If (Register And &H3FFF) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
Why is this happening and is there a work-around?
Your literal values are implicitly typed as long (Int64), since you didn't specify a type for them. I actually got the overflow on the assignment to Register, since the value given is too big for a long. To get this to work, just specify the type for your literal values, e.g. UL for unsigned long:
Dim Register As UInt64
Register = 12297264199100303880UL
If (Register And &H3FFFUL) = &H555UL Then
MsgBox("Done")
End If
Turning Option Strict On would be helpful, in this case. If you did, you would immediately see the problem. The problem is that the literals are interpreted as Integer (Int32) rather than ULong (UInt64). In order to force the literal to be interpreted as a ULong values, you need to add the UL type suffix:
Dim Register As UInt64
Register = 12297264199100303880UL
If (Register And &H3FFFUL) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
I fixed this by:
Dim DoneMask As UInt64 = &H3FFF
Dim Register As UInt64
Register = 12297264199100303880
If (Register And DoneMask) = &H555 Then ' Get Overflow exception here
MsgBox("Done")
End If
Apparently VB does better with explicit data types instead of a literal

Check string in an array

I have strings stored in an array and need to check if the 5th character of each string is a number or not. The code I used is:
If Mid(arr(i), 5, 1) = IsNumeric(True) Then
MsgBox("Number")
End If
It is giving an error:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Boolean' is not valid.
You originally tagged your question as vba, but VBA doesn't throw System.InvalidCastException, or any other exception for that matter; vb.net does.
IsNumeric(True) returns True if True is numeric. You want to verify if the string retrieved from the array is numeric; give it the string retrieved from the array as a parameter:
If IsNumeric(Mid(arr(i), 4, 1)) Then
MsgBox("Number")
End If
Your code reads like VB6/VBA though, because of this:
Imports Microsoft.VisualBasic
That namespace contains VB6-like things that you don't need to use at all. The beauty of .net is that everything is an object, so assuming the array is an array of String, you can call the actual String instance methods instead of VB6's Mid function.
Dim theFifthCharacter As String = arr(i).Substring(4, 1)
Or, because you're only interested in 1 character, and a String is itself an IEnumerable(Of Char), you can do this:
Dim theFifthCharacter As Char = arr(i)(4)
Notice the off-by-one - in .net indices start at 0, so if you want the 5th item you'll fetch index 4.
Now, if you want to see if it's numeric, you can try to parse it:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
Else
'non-numeric: digitValue contains an Integer's default value (0)
End If
Lastly, if you want a message box, use WinForms' MessageBox instead of VB6's MsgBox:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
MessageBox.Show(string.Format("Number: {0}", digitValue))
Else
'non-numeric: digitValue contains an Integer's default value (0)
MessageBox.Show("Not a number")
End If
A more correct way to do this would be:
If Char.IsDigit(arr(i)(4)) Then
Your syntax is incorrect. It should be:
If IsNumeric(Mid(arr(i), 5, 1)) Then

Impicit conversion warning

I am doing this simple operation with a string in VB.NET
I have a string of information called segmentInfo looking like this:
XRT0034:3:89:23
So I am just trying to get a number out of it:
Dim rowNum As Integer = segmentInfo.split(":")(1)
And I am getting actually 2 warnings. Both warning are given on the same line of code.
Warning - Implicit conversion from 'String' to 'Integer'
Warning - Implicit conversion from 'String' to 'Char'
Maybe I could understand the first one, about the string to integer...but the second one?? I do not understand.
Anyway, can anybody tell me what I am doing wrong and how to fix it?
The Split method takes a Char (array) as a parameter, not a string. Hence:
.... segmentInfo.split(":"c)(1)
Secondly, you need to parse the resulting string to an integer:
Dim rowNum As Integer = Integer.Parse(segmentInfo.split(":"c)(1))
Do this only when you know that the string is a number. Otherwise, use TryParse.
No such overload method String.Split which take one parameter of type String
From MSDN String.Split Method
You can change to
Dim rowNum As Integer = segmentInfo.split(":"c)(1)
":"c - c is character of type Char Type Characters (Visual Basic)
For converting String to Integer use Int32.TryParse or Int32.Parse method to convert string to integer
Dim rowNum As Int32 = Int32.Parse(segmentInfo.split(":"c)(1))
'Exception will be thrown if string value not convertible to Integer type
Or
Dim rowNum As Int32
If Int32.TryParse(segmentInfo.split(":"c)(1), rowNum) = True Then
'Use succesfully converted integer value
Else
'Show message about invalid text
End If
You must parse it to integer form
Dim rowNum As Integer = Convert.ToInt32(segmentInfo.split(":")(1))
Dim rowNum As Integer = Integer.Parse(segmentInfo.split(":"c)(1))

Calling VBScript Procedure results type mismatch error

One of my COM object has a following member which returns byte array and its lengh in the second argument.
HRESULT GetBinaryData([out] VARIANT *pVal, [out] long *pLen);
FYI,
**Part of implementation is as follows:**
....
VariantInit(pVal);
pVal->vt = VT_UI1 | VT_ARRAY;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = ARRAY_LBOUND;
rgsabound[0].cElements = (ULONG)len;
pVal->parray = SafeArrayCreate(VT_UI1, 1, rgsabound);
....
I am trying to invoke this memeber in VBScript but failed in all of my trials. Here is my vbscript code snippet:
Set op = CreateObject("myserver")
dim bytearray()
op.GetBinaryData bytearray, bytearray_len
But at line 3, Type mismatch error is encountered...
How can I get the result from the procedure into my vbscript variables?
Thanks in advance.
Consider using retval at the COM level:
HRESULT GetBinaryData([out, retval] VARIANT *pVal);
since the return value is a SAFEARRAY your existing C++ will still work. In this case, SAFEARRAY is a sufficient return to give the caller both the array and the length. i.e. your C++ code remains as-is.
Your VBScript code becomes:
Option Explicit
Set op = CreateObject("myserver")
Dim byteArray, lenArray
byteArray = op.GetBinaryData()
lenArray = UBound(byteArray) - LBound(byteArray) + 1
Although you can only have one retval by means of SAFEARRAY or an equivalent object (e.g. IXMLDOMDocument) you can package a number of return values for VBScript.