Object reference not set to an instance of an object? VB.NET - vb.net

I have this code here:
Dim MasterIndex As String()()
Private Function Lookup(ByVal Search_path As String) As Integer
Dim i As Integer = 0
Do Until MasterIndex(i)(0) Is Nothing
If Search_path = MasterIndex(i)(0) Then
Return MasterIndex(i)(1)
End If
Loop
Return -1
End Function
Which gives me the error Object reference not set to an instance of an object occuring on the Do Until line. Why is this? How can I fix this?

The MasterIndex variable is never assigned that is why you have the exception
You should instantiate MasterIndex first by calling the New() constructor:
Dim MasterIndex As new String()()
and fill it with data before calling the Lookup function.
Something like:
Private MasterIndex As String()() = New String()() {New String() {"A1", "A2"}, New String() {"B1", "B2"}}

Either MasterIndex is not initialized or MasterIndex(0) is not initialized.
Can you show the code that initializes that variable, assuming you do that somewhere else in the program?
What happens if you put a breakpoint on that line and examine MasterIndex?

Related

vb.net running a exe in memory

I'm trying to run a app on memory but I'm having error at Invoke. What am I doing wrong?
I'm trying to do this but in vb.net
Code C#
// read the bytes from the application exe file
FileStream fs = new FileStream(filePath, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
fs.Close();
br.Close();
// load the bytes into Assembly
Assembly a = Assembly.Load(bin);
// search for the Entry Point
MethodInfo method = a.EntryPoint;
if (method != null)
{
// create an istance of the Startup form Main method
object o = a.CreateInstance(method.Name);
// invoke the application starting point
method.Invoke(o, null);
}
in vb:
Dim instance As FileStream = File.Open("teste.exe", FileMode.Open)
Dim br As New BinaryReader(instance)
Dim bin As Byte() = br.ReadBytes(Convert.ToInt32(instance.Length))
instance.Close()
br.Close()
Dim a As Assembly = Assembly.Load(bin)
Dim metodo As MethodInfo = a.EntryPoint
If (IsDBNull(metodo) = False) Then
'create an istance of the Startup form Main method
Dim o As Object = a.CreateInstance(metodo.Name)
'invoke the application starting point
metodo.Invoke(o, Nothing)
Else
MessageBox.Show("Nao encontrado")
End If
UPDATE:
I found the answer. I created the "test.exe" like a ConsoleAplication, than in the module I code
Imports System.Windows.Forms
Module Module1
Sub Main()
Dim Form1 As New Form1
Form1.Show()
Do Until Form1.Visible = False
Application.DoEvents()
Loop
End Sub
End Module
Then I changed from ConsoleApplication to Windowsform And create my Form1. And this
metodo.Invoke(o, Nothing)
to this:
metodo.Invoke(Nothing, New Object() {})
Thank you guys for the support!
The Main method expects that you pass it the args parameter. Your current call is not passing any parameters, so I'm expecting that you are getting the following error if it ever reaches that line:
System.Reflection.TargetParameterCountException: Parameter count mismatch.
To fix it, just pass a one-element object array as the second parameter of the method.Invoke. Also, because the Main method is a static method, you don't need to do a CreateInstance before invoking the method.
So all you need is this:
metodo.Invoke(Nothing, New Object() {Nothing})
If, for some reason, you actually need pass values to the main's args parameter, you can do it like this:
metodo.Invoke(Nothing, New Object() {New String() {"param1", "param2"}})
Assuming the c# code works you mistranslated the null check.
The equivalent of 'if (method != null)' in vb.net is
If method IsNot Nothing Then
Dim o = a.CreateInstance(method.Name)
method.Invoke(o, Nothing)
End If

VBA assigning to array

In the code snippet I create an array of string and want to assign it to another.
Dim rfms(0) As String
rfms(0) = "X"
The next line is not working
Me.SelectedRfms = rfms
But when I created the next function:
Function ReturnTheArrayInParamter(p() As String) As String()
ReturnTheArrayInParamter = p
End Function
This is working:
Me.SelectedRfms = ReturnTheArrayInParamter(rfms)
The definition of Me.SelectedRfms is the next:
Private pSelectedRfms() As String
''''''''''''''''''''''
' SelectedRfms property
''''''''''''''''''''''
Public Property Get SelectedRfms() As String()
SelectedRfms = pSelectedRfms
End Property
Public Property Let SelectedRfms(value() As String)
pSelectedRfms = value
End Property
Can you explain why the first one is not working and why the second is working.
You cannot assign an array declared with a fixed size to a property, use:
ReDim rfms(0) As String
(The indirect function does not use a fixed size array)

VB Web Service call error Object reference not set

Hey all I am trying to figure out why I am getting the following error:
Object reference not set to an instance of an object.
on line 2 of code:
1. Dim HTPCws As HTPCWS.ServiceVB
2. Dim returned As String = HTPCws.DisplayMessageVB(what2send)
When I know what2send does have a value to send....
The Web Service code is this:
<WebMethod()> Public Function DisplayMessageVB(ByVal beingSent As String) As String
_strfromws = beingSent
Return "DONE"
End Function
What could I be forgetting?
HTPCws has not been instantiated. Change the code to:
Dim HTPCws = New HTPCWS.ServiceVB()
Dim returned As String = HTPCws.DisplayMessageVB(what2send)
Dim HTPCws As HTPCWS.ServiceVB declares a variable but does not assign it an object. Also the naming is a bit confusing. Better:
Dim service = New HTPCWS.ServiceVB()
Dim returned As String = service.DisplayMessageVB(what2send)

Programatically setting an object array's object

I have
Public stack() As CTest
I want
Public stack() As Object
The latter is giving the error "Unable to cast object of type 'Object' to 'CTest'." when used:
Dim thestack As CTest() = testdatabase.getStack
Where testdatabase.getStack simply returns stack();
Public Function getStack() As Object()
Return stack
End Function
This fixes it, but it's not ideal (for me personally):
Dim thestack As Object() = testdatabase.getStack
So if I could keep the variable as-is (Public stack() As Object) and then do something along the lines of class.stack() = CTest I should be able to do Dim thestack As CTest() = testdatabase.getStack because the object array will programmatically have changed from Object to CTest.
Is this possible at all?
One way to approach this would be to write a conversion function that accepts Object and returns CTest. The function itself would cast Object to the boxed datatype, assign the value of each property on the object to the new CTest object and then return it. Something like this:
Function ConvertToCTest(o as Object) as CTest
dim unboxed as ObjectsDataType
unbox = directCast(o ObjectsDataType)
Dim result as CTest
result.Prop1 = unboxed.Prop1
result.Prop2 = unboxed.Prop2
Return result
End Function

How can I copy an object of an unknown type in VB.net?

Rather than giving the very specific case (which I did earlier), let me give a general example. Let's say that I have a function, called callingFunction. It has one parameter, called parameter. Parameter is of an unknown type. Let us then say that I wish to copy this parameter, and return it as a new object. For example, in pseudo code, something along the lines of...
Function callingFunction(ByVal parameter As Object) As Object
Dim newObj As New Object
'newObj has the same value as parameter, but is a distinctly different object
'with a different reference
newObj = parameter
return newObj
End Function
EDIT: Additional Information
The first time I posted this question, I received only one response - I felt that perhaps I made the question too specific. I guess I will explain more, perhaps that will help. I have an ASP page with 10 tables on it. I am trying, using the VB code behind, to come up with a single solution to add new rows to any table. When the user clicks a button, a generic "add row" function should be called.
The difficulty lies in the fact that I have no guarantee of the contents of any table. A new row will have the same contents as the row above it, but given that there are 10 tables, 1 row could contain any number of objects - text boxes, check boxes, etc. So I want to create a generic object, make it of the same type as the row above it, then add it to a new cell, then to a new row, then to the table.
I've tested it thoroughly, and the only part my code is failing on lies in this dynamic generation of an object type. Hence why I asked about copying objects. Neither of the solutions posted so far work correctly, by the way. Thank you for your help so far, perhaps this additional information will make it easier to provide advice?
You can't do this in general. And it won't be a good idea, for example, if parameter is of a type which implements the singleton pattern. If parameter is of a type which supports copying, it should implement the ICloneable interface. So, your function could look like this:
Function MyFunc(ByVal parameter As Object) As Object
Dim cloneableObject As ICloneable = TryCast(parameter, ICloneable)
If Not cloneableObject Is Nothing Then
Return cloneableObject.Clone()
Else
Return Nothing
End If
End Function
You could implement something like this:
Dim p1 As Person = New Person("Tim")
Dim p2 As Object = CloneObject(p1)
Dim sameRef As Boolean = p2 Is p1 'false'
Private Function CloneObject(ByVal o As Object) As Object
Dim retObject As Object
Try
Dim objType As Type = o.GetType
Dim properties() As Reflection.PropertyInfo = objType.GetProperties
retObject = objType.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, o, Nothing)
For Each propertyInfo As PropertyInfo In properties
If (propertyInfo.CanWrite) Then
propertyInfo.SetValue(retObject, propertyInfo.GetValue(o, Nothing), Nothing)
End If
Next
Catch ex As Exception
retObject = o
End Try
Return retObject
End Function
Class Person
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal name As String)
Me.Name = name
End Sub
End Class
Here's a simple class that will work for most objects (assumes at least .Net 2.0):
Public Class ObjectCloner
Public Shared Function Clone(Of T)(ByVal obj As T) As T
Using buffer As MemoryStream = New MemoryStream
Dim formatter As New BinaryFormatter
formatter.Serialize(buffer, obj)
buffer.Position = 0
Return DirectCast(formatter.Deserialize(buffer), T)
End Using
End Function
End Class