来自 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.
我正在用 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.