``
I have a C# class library project (.Net Framework 4.5) that I use it in VB6 as a type library (.tlb).
Everything works fine with properties with non-collection objects as attributes or returns.
As far as I know, it's not possible to expose a collection (Array/List) of a user-type object such as Product []
in a C# project and export it to tlb file, but Object []
I heard it's okay. So, I changed:
Public List<Product> ListOfProducts( get; set; )
to
Object [] _productList;
public Object [] ListOfProducts
{
get
{
return _productList;
}
set
{
_productList = value;
}
}
I also tried:
public void SetListOfProducts(Object [] products)
{
_productList= products;
}
That done, ListOfProducts
or SetListOfProducts
now are visible in Visual Basic 6 project, but in VB6, when I run:
Private Sub Command1_Click()
Dim Sell as new SellProducts
Dim prodct(1) As New TlbProj.Product 'Product is a class inside of the tlb file
prodct(0).EAN = "7894900011517"
prodct(1).EAN = "7894900017011"
Dim prodctVariant(1) As Variant
'Set prodctVariant = prodct or prodctVariant = prodct throws "Can't assign to array error"
prodctVariant(0) = prodct(0) 'one by one was the only way I managed to do this. That's not the major problem.
prodctVariant(1) = prodct(1)
Sell.ListOfProducts = prodctVariant
'The object browser shows: 'Property ListOfProducts As Variant()
'it throws the message: "Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic"
Sell.SetListOfProducts prodctVariant
'The object browser shows: 'Sub SetListOfProducts(products() As Variant)
'it throws the message: "Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic"
End Sub
My classes:
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("757E6144-FC46-44A0-89DB-B89EF8F75BAB")]
[ProgId("TlbProj.SellProducts")]
[ComVisible(true)]
public Class SellProducts
{
Object [] _productList;
public Object [] ListOfProducts
{
get
{
return _productList;
}
set
{
_productList = value;
}
}
public void SetListOfProducts(Object [] products)
{
_productList= products;
}
}
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("A4292449-4459-42D4-8FB0-18AA0D5FF34A")]
[ProgId("TlbProj.Product")]
[ComVisible(true)]
public class Product
{
public string EAN { get; set; }
}
I have tried with no success:
That said, is there a way to get and set Array of Object (preferably to Array of Product type) from C# to COM, even using .Net 5+? Thank you all!
Although .NET creates valid type libraries, they are not all supported by VB6. .NET generics cannot be used at all at boundaries.
One solution is to use ArrayList as a collection type usable in C# and VB6 but it's untyped. It works with .NET Framework, but not sure it still works (registered?) with .NET Core3+.
Here is a solution that works and is typed for reading the list, but is untyped for write operations:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("757E6144-FC46-44A0-89DB-B89EF8F75BAB")]
[ProgId("TlbProj.SellProducts")]
public class SellProducts
{
private readonly List<Product> _products = new List<Product>();
public SellProducts()
{
_products.Add(new Product { EAN = ".NET1234" });
_products.Add(new Product { EAN = ".NET5678" });
}
// read only mode
public Product[] Products => _products.ToArray();
// write mode, untyped :-(
public void SetProducts(object products)
{
_products.Clear();
if (products is IEnumerable enumerable)
{
_products.AddRange(enumerable.OfType<Product>());
}
}
}
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("A4292449-4459-42D4-8FB0-18AA0D5FF34A")]
[ProgId("TlbProj.Product")]
[ComVisible(true)]
public class Product
{
public string EAN { get; set; }
}
VB6 doesn't understand type libs created with object[]
or Product[]
parameters for SetProducts.