按值将C#对象传递给COM

Bas*_*ink 7 c# com com-interop marshalling

我正在尝试使用来自C#的COM接口,它暴露了由tlbimp生成的以下接口:

[Guid("7DDCEDF4-3B78-460E-BB34-C7496FD3CD56")]
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
public interface IFred 
{
    [DispId(1)]
    IBarney Pall { get; set; }
}

[Guid("E390230E-EE9C-4819-BC19-08DAB808AEA9")]
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
public interface IBarney
{
    [DispId(1)]
    double Wilma { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

生成的包装程序集不包含IBarney接口的实现.我已经创建了一个C#结构来实现这样的IBarney接口:

[Guid("2C61BA37-7047-43DB-84B1-83B4268CF77B")]
[ComVisible(true)]
public struct Barney : IBarney
{
    public double Wilma { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

哪个"有效",现在的问题是,一个Barney实例是通过价值还是通过参考进行整理?由于涉及网络开销,这很重要.理想情况下执行以下操作:

fredInstance.Pall = new Barney { Wilma = 0.37 };
Run Code Online (Sandbox Code Playgroud)

将导致单个网络往返.我如何验证这一点,或者如何告诉COM互操作我的Barney结构应该始终按值进行编组?

更新:

鉴于Hans Passant的评论.设计这个的"正确"方法是什么?允许简单结构作为COM接口的"属性"值使用的IDL是什么?查看从中生成接口的IDL,我正在使用添加coclass带默认IBarney接口的声明就足够了,对吧?

Jos*_*son 1

一些评论...不知道这是否会是答案...

1)我认为你应该让你的界面 [ComVisible(true)]

2)为什么将Barney定义为结构体?应该是一个类。与 C++ 不同,C++ 中类和结构之间的唯一区别是私有成员与公共成员的默认值,而 C# 结构和类有着根本的不同。