Accessing Arrays

.NET Arrays require special attention when called through COM interop from Visual FoxPro because Visual FoxPro doesn't recognize .NET arrays as objects but tries to coerce them into FoxPro arrays. While it's possible to read a .NET array passed over COM, you cannot easily manipulate the array by adding and removing items. Specifically it's not possible to use array for anything but reading and updating existing items as marshaling into FoxPro removes the full type information of the array/collection/list.

wwDotnetBridge provides a ComArray helper class that wraps arrays and keeps them in .NET and this class can be used with indirect access to .NET object via InvokeMethod/SetProperty/GetProperty of wwDotNetBridge. This is probably the easiest way to deal with .NET arrays and we recommend you try that first.

Native Array COM access from Visual FoxPro

If for some reason ComArray doesn't work for you or you prefer to deal with arrays directly in FoxPro you can get at arrays natively using code like this:

loBridge = CREATEOBJECT("wwDotNetBridge")
loBridge.LoadAssembly("Westwind.WebConnection.wwDotNetBridgeSamples.dll");  && local path

loItem = loBridge.CreateInstance("Westwind.WebConnection.VfpTestClass")

*** ASSUME: there's a PersonArray property defined with 2 initialized array elements

*** Access the array - this explicit assignment is REQUIRED!!!
loPersonsArray =  loItem.PersonArray

*** Now use as a VFP array - but you can't add/remove items and effect .NET
? loPersonArray[0].Name
? loPersonsArray[1].Name

*** Fails because the .NET array has turned into a VFP array
* ? loPersonsArray.Length

The problem is that the actual array type - a .NET object - is not COM visible and receiving a .NET array FoxPro converts it into a FoxPro array. You can read the items and update existing items that are already defined on the array but there's no effective way to manipulate the array by adding or removing items. Once you add or remove items the array cannot be passed back to .NET. Not terribly useful.

To help with array manipulation wwDotNetBridge provides several helper methods to access arrays. These helper methods require a base object - an object that the array is declared on - so that the array can be entirely manipulated in .NET code:

  • CreateArrayOnInstance
  • AddArrayItem
  • GetArrayItem
  • RemoveArrayItem
  • GetPropertyEx (for reading array properties and items)

The following code demonstrates these features in action. Assume an ArrayList declaration like this in VfpTestClass:

using System;
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class VfpTestClass
{
    
    public ArrayList Persons
    {
        get { return _Persons; }
        set { _Persons = value; }
    }
    private ArrayList _Persons = new ArrayList();
}
    
public class Person
{
	
    public string Name
    {
      get { return _Name; }
      set { _Name = value; }
    }
    private string _Name = "Rick";

    
    public string Company
    {
      get { return _Company; }
      set { _Company = value; }
    }
    private string _Company = "West Wind";

}

Using wwDotNetBridge you can manipulate this array in the following ways:

DO wwDotNetBridge

loBridge = CREATEOBJECT("wwDotNetBridge")
loItem = loBridge.CreateInstance("Westwind.WebConnection.VfpTestClass")

*** Create a new person object
loPerson = loBridge.CreateInstance("Westwind.WebConnection.Person")
loPerson.Name = "Jim johnson"
loPerson.Company = "Temporary traders"

*** Create one element array and set the first slot to loPerson
loBridge.CreateArrayOnInstance(loItem,"Persons",loPerson)

*** Retrieve it so we can see it worked
loPerson = loBridge.GetArrayItem(loItem,"Persons",0)
? loPerson.Name
? loPerson.Company

*** Create another new item
loPerson = loBridge.CreateInstance("Westwind.WebConnection.Person")
loPerson.Name = "Billy Bopp"
loPerson.Company = "Boppers Inc."

*** And add it to the existing array
loBridge.AddArrayItem(loItem,"PersonArray",loPerson)

*** Get the length of the array - 2 items
? loBridge.GetPropertyEx(loItem,"PersonArray.Length")

*** Read new item (element 1) back from the .NET object
loPerson = loBridge.GetArrayItem(loItem,"PersonArray",1)
? loPerson.Name
? loPerson.Company



*** Null out the array
loBridge.SetPropertyEx(loItem,"PersonArray",null)

*** Create a new array - this time empty array with 2 items
*** This would also be equivalent of an existing empty array from .NET
? loBridge.CreateArrayOnInstance(loItem,"PersonArray",2)

*** Create a new person
loPerson = loBridge.CreateInstance("Westwind.WebConnection.Person")
loPerson.Name = "Jim johnson"
loPerson.Company = "Temporary traders"

*** Assign it to the first Item
loBridge.SetPropertyEx(loItem,"PersonArray[0]",loPerson)

*** Create another new person
loPerson = loBridge.CreateInstance("Westwind.WebConnection.Person")
loPerson.Name = "Frank Bolski"
loPerson.Company = "Proletarian Master Traders"

*** Assign it to the second Item
loBridge.SetPropertyEx(loItem,"PersonArray[1]",loPerson)


*** Get the length of the array - 2 items
? loBridge.GetPropertyEx(loItem,"PersonArray.Length")

loPerson = loBridge.GetArrayItem(loItem,"PersonArray",1)
? loPerson.Name
? loPerson.Company

RETURN

© West Wind Technologies, 2004-2017 • Updated: 04/27/17
Comment or report problem with topic