Problem passing the result of an ArrayList from external library

moster67

Expert
Licensed User
Longtime User
Hi - I have problems in getting values of an ArrayList produced in an external library. This works in VB.NET but not in Basic4PPC.

My library in VB.NET exposes the following property:

B4X:
Public ReadOnly Property ReturnSuggestions() As ArrayList
   Get
      Return ResultSuggestions
   End Get
End Property

Note: ResultSuggestions has been declared in a module in my library as an ArrayList as follows:

B4X:
Public ResultSuggestions As New ArrayList()

When I call ReturnSuggestions from a sample program in VB.NET which uses my library, everything is OK. This is how I call it:

B4X:
Private Sub CheckSuggestionsAvailable()
   If CheckSpelling.ReturnSuggestions.Count > 0 Then
      For i As Integer = 0 To CheckSpelling.ReturnSuggestions.Count - 1
          ListBox1.Items.Add(CheckSpelling.ReturnSuggestions.Item(i).ToString.ToLower)
      Next
   End If
End Sub

However, calling it from Basic4PPC doesn't work. This is my code:

B4X:
If  detect.ReturnSuggestions.count > 0 Then
                For i =0 To detect.ReturnSuggestions.count - 1
      listbox1.Add(StrToLower(detect.ReturnSuggestions.item(i)))
       Next
End If

where "detect" is an instance previously initiated by using detect.new1.

If Basic4PPC recognized detect.ReturnSuggestions as an ArrayList, I guess that Basic4PPC's Intelisense would suggest methods such as "count" but it doesn't.

Any ideas?

It works in VB.NET but not in Basic4PPC. Perhaps I must add something specific to my library so it works with Basic4PPC?

Rgds,
moster67
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Basic4ppc can't directly access nonprimitive objects from an external library.
The solution is to first pass the object to a Basic4ppc object.
This is usually done with something like Node.Value = Tree.SelectedNode.
However Basic4ppc internal controls don't have this "Value" property.
Currently the simplest solution is to use a regular array instead of an ArrayList.
Then from Basic4ppc you will be able to get the external array with:
B4X:
myArr() = detext.ReturnSuggestions
 

moster67

Expert
Licensed User
Longtime User
Thanks,

OK, I will modify the library to use a regular array instead

moster67

Currently the simplest solution is to use a regular array instead of an ArrayList.
Then from Basic4ppc you will be able to get the external array with:
B4X:
myArr() = detext.ReturnSuggestions
 

moster67

Expert
Licensed User
Longtime User
BTW: just out of curiosity: Which objects are nonprimitive? Apart from ArrayList, can you name any other other ones?

Thanks,
moster67
 

agraham

Expert
Licensed User
Longtime User
Use an Arraylist in the library if it is more convenient then pass it back as "return myArrayList.ToArray()" making sure that the items of the array are the types of object that Basic4ppc expects. That is

Dim Returns(0) ' needs strings
Dim Returns(0) As Int32 ' needs ints
Dim Returns(0) As Boolean ' needs bools
... ' you get the picture

See Help->Main Help->Basics->Data types for a list of types allowed.

Which objects are nonprimitive?
It's easier to say which objects are primitive. Basically numbers, booleans and strings. Technically these are "value types" which are passed around by value, all other types are "reference types" which are passed around as pointers to the actual objects. Strings are actually reference types but they behave like value types and are said to have "value semantics". Basic4ppc can only handle value types and strings itself but can pass reference types between libraries as in Erels' example.
 

moster67

Expert
Licensed User
Longtime User
Thank you my friends !

I have adapted the library as suggested and now the problem posted in this thread has been resolved.

Hopefully the library is now fully compatibile with Basic4ppc otherwise I reserve the right to get back to you for further help :)

rgds,
moster67
 

moster67

Expert
Licensed User
Longtime User
Omg

Well, I thought I had resolved this problem using your suggestions.

I was stupid enough to consider it "resolved" when I noted that the code worked in debugging-mode but only to find out that once compiled (optimized) and ran (both on PPC and Desktop), I get the following error:

"Unable to cast object of type 'System.Object[]' to type 'System.String[]'. "

I did the changes as suggested by you:

1) in my library:

B4X:
Public ReadOnly Property ReturnSuggestions() As Array
        Get
            Return ResultSuggestions.ToArray
        End Get
End Property

2) in Basic4ppc:

B4X:
Sub Globals
   'Dim SuggestionResults(0) as string
   Dim SuggestionResults(0)
             'I tried both - no difference
End Sub

Above error-message in Basic4ppc appears in this part:

B4X:
SuggestionResults()=detect.ReturnSuggestions   'OK

Msgbox("No. of Sugg.: " & ArrayLen(SuggestionResults()))   'OK

   For i = 0 To ArrayLen(SuggestionResults()) -1  'OK
      Msgbox(SuggestionResults(i)) '-> ERROR
   Next

I am pretty sure that the items in the array are strings.

Any ideas?

Thanks.

rgds,
moster67
 
Last edited:

moster67

Expert
Licensed User
Longtime User
I will try a "workaround" which would mean that I return the results (i.e. the suggestions) from my library as a "concatened string" instead of an array.

Once received in Basic4ppc, I could use Split to separate each word and add them to an array and then proceed as usual.

However, if anyone has any ideas as to the error mentioned above and how to resolve it, I'd love to hear from you.

thanks,

rgds,
moster67
 

agraham

Expert
Licensed User
Longtime User
Sorry, I think I missed a out a step.
B4X:
Public ReadOnly Property ReturnSuggestions() As Array
        Get
            Return ResultSuggestions.ToArray
        End Get
End Property
I don't do VB.NET but I think this is returning an array of objects, not an array of strings, or anything else. String, Bools etc. are all objects so this works to pass the array but Basic4ppc, in your case, is expecting a string array when you reference it in MsgBox.

In C# I would do
B4X:
Public TypeInArrayList[] ReturnSuggestions
{ get { return (TypeInArrayList[]) ResultSuggestions.ToArray(); } }
or
Public TypeInArrayList[] ReturnSuggestions
{ get { return  ResultSuggestions.ToArray(typeof(TypeInArrayList); } }
to cast the array to an array of whatever type I knew the contents of the ArrayList to be and what Basic4ppc is expecting. I don't know the exact VB syntax but you could try "ReturnSuggestions() Array As String" for the return type or "ToArray(typeof(TypeInArrayList)". I started in .NET using VB.NET but I'm afraid that I quickly switched to C# because of the tortuous syntax involved in getting strong typing correct in VB.
 

moster67

Expert
Licensed User
Longtime User
Thanks Graham!

Now it works.

I changed my property in the library as follows:

B4X:
Public ReadOnly Property ReturnSuggestions() As String()
        Get
            Return ResultSuggestions.ToArray(GetType(String))
        End Get
End Property

That was not an easy one - at least for me. Thanks for helping me out! I am learning something new everyday.

rgds,
moster67
 
Last edited:
Top