VB中的COM对象数组

时间:2016-12-05 13:07:16

标签: c# arrays vb.net vba com

我正在使用C#,Visual Studio 2010,.NET 3.5,x86开发一个COM对象 我在VBA程序中使用它。

namespace Test
{
    [Guid("8b65089f-5d98-41e7-9579-1ee384948e4c")]
    [ComVisible(true)]
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct Contact
    {
        [MarshalAs(UnmanagedType.BStr)] 
        public string Test1;
        public string[] Array;
    }


    [Guid("8b65082f-5d98-41e7-9579-1ee384948e4e"), ComVisible(true)]
    public interface IInContainer
    {
        Contact[] Contacts { [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] get; set; }
        string[] strings { [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] get; set; }

    }

    [Guid("8b65089f-5d98-41e7-9579-1ee384948e4b"), ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
    public class InContainer
    {
        //[MarshalAs(UnmanagedType.BStr)]
        public Contact[] Contacts { get;set;}
        public string[] strings { get; set; }
    }

}

当我创建它时,我能够在VB中看到对象的结构/接口。

我可以毫无问题地从VB更改Container.strings中的信息。

但是,我无法通过VB更改Contact数组中的信息(使用Contact结构)。

让我们说Contact数组i 1 long,该节点的所有值都设置为“test”。当试图通过VB改变它,即Container.Contact(0).Test1 = "Monkey"我没有错误。当尝试在Print(Container.Contact(0).Test1)之后直接读取它时,我得到“”,或者我设置的任何默认字符串。

我可以使用容器对象上的方法更改联系人中的信息,但这是不可取的。

所以我需要帮助,为什么只在Container.Contact数组中读取值。

1 个答案:

答案 0 :(得分:2)

您基本上是编辑结构的副本,在您的分配后直接丢弃该结构(因为它不保存在变量中)。

如果你分解Container.Contact(0).Test1 = "Monkey",你会得到以下内容:

  • 创建索引0处Contact项的副本(因为结构是值类型)
  • 在联系人的副本上为属性Test1分配值“Monkey”
  • 将丢弃具有已修改Test1属性的联系人结构的副本
  • 调用Print(Container.Contact(0).Test1)时,将再次复制仍在数组中的原始Contact结构,并打印此新创建的副本的Test1属性。

一种解决方案是将Contact类型从struct更改为class 1 ,或者替换指定数组索引处的整个struct而不是尝试仅更改单个属性或字段

dim cntct as Contact
cntct = Container.Contact(0)
cntct.Test1 = "Monkey"
Container.Contact(0) = cntct

1 除非您确定此处需要结构,否则您可能希望从struct更改为class。