来自 VB 的 COM 对象数组

COM Object Arrays From VB

我正在用 C# 开发 COM 对象,Visual studio 2010,.NET 3.5,x86 我在 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 中看到对象的 structure/interface。

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

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

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

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

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

你基本上是在编辑结构的副本,它在你赋值后直接被丢弃(因为它没有保存在变量中)。

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

  • 在索引 0 处创建了 Contact 项的副本(因为结构是值类型)
  • 属性 Test1 在联系人
  • 的副本 上分配了值 "Monkey"
  • Test1 属性 修改后的联系人结构副本被丢弃
  • 当调用Print(Container.Contact(0).Test1)时,仍然在数组中的原始联系结构被再次复制,并打印这个新创建的副本的Test1 属性。

一个解决方案是将您的 Contact 类型从结构更改为 class1,或者替换指定数组索引处的整个结构而不是尝试仅更改一个 属性 或字段。

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

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