如何通过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;