如何通过COM Interop访问复杂对象的属性?

问题描述:

所以我有一个接口(IInterface1)公开为ComVisible(true),ClassInterfaceType(ClassInterfaceType.None)。如何通过COM Interop访问复杂对象的属性?

我有该接口,丙氨酸的对象:

public interface IInterface1 
{ 
    Object1 object {get; set;} 
} 

对象一个也被标记有ComVisible特性(真),是在一个单独的组件,ClassInterfaceType(ClassInterfaceType.None),看起来像这样:

public interface IObject1 
{ 
    string MyProperty {get;set;} 
} 

在C#的是,我有下面的类:

public class Interface1 : IInterface1 
{ 
    public IObject1 Object1 {get;set;} 
} 

从非托管C++,我将如何访问Interface1.Object1.MyProperty?我正在导入TLH raw_interfaces_only,可以CreateInstance我的Interface1类,并访问Object1。如果我尝试访问Object1上的MyProperty,则会得到“不允许的不完整类类型指针”。

C++代码的样子:

Assembly1::Interface1Ptr interface1ptr; 
HRESULT hrRetval = CoInitialize(NULL); 
hrRetval = interface1ptr.CreateInstance(__uuidof(Assembly1::Interface1)); 
Assembly1::Object1 *object1; 

hrRetval = interface1ptr.get_Object1(&object1); 

这是我坚持:

hrRetval = object1->get_MyProperty(varToStore); // This doesn't work. 

欣赏任何指针(HAR HAR)。

你可以只导入这两个组件,这应该是它:

Assembly1:

namespace ClassLibrary1 
{ 
    [ComVisible(true)] 
    public interface IObject1 
    { 
     string MyProperty { get; } 
    } 

    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.None)] 
    public class Object1 : IObject1 
    { 
     public string MyProperty { get => "42"; } 
    } 
} 

// AssemblyInfo.cs 
[assembly: Guid("d1e7f7b4-3c3a-41e5-b0bf-5dec54050431")] 

Assembly2:

namespace ClassLibrary2 
{ 
    [ComVisible(true)] 
    public interface IInterface1 
    { 
     IObject1 Object1 {get;} 
    } 

    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.None)] 
    public class Interface1 : IInterface1 
    { 
     public IObject1 Object1 { get => new Object1(); } 
    } 
} 

// AssemblyInfo.cs 
[assembly: Guid("a7a14989-71da-49d4-87be-85c4b87bcaf0")] 

C++:

#include "stdafx.h" 
#import "libid:d1e7f7b4-3c3a-41e5-b0bf-5dec54050431" raw_interfaces_only 
#import "libid:a7a14989-71da-49d4-87be-85c4b87bcaf0" raw_interfaces_only 

int main() 
{ 
    CoInitialize(nullptr); 

    ClassLibrary2::IInterface1Ptr i1; 
    i1.CreateInstance(__uuidof(ClassLibrary2::Interface1)); 

    ClassLibrary1::IObject1Ptr o1; 
    i1->get_Object1(&o1); 

    BSTR bstr; 
    o1->get_MyProperty(&bstr); 

    CoUninitialize(); 
    return 0; 
} 

BTW,是有一些s特别的原因你为什么要raw_interfaces_only?没有它会更容易和更安全:

ClassLibrary2::IInterface1Ptr i1; 
i1.CreateInstance(__uuidof(ClassLibrary2::Interface1)); 

auto o1 = i1->Object1; 
auto bstr = o1->MyProperty;