【问题标题】:How do I access a complex object's properties via COM Interop?如何通过 COM 互操作访问复杂对象的属性?
【发布时间】:2017-10-05 20:41:11
【问题描述】:

所以我有一个接口 (IInterface1) 公开为 ComVisible(true)、ClassInterfaceType(ClassInterfaceType.None)。

我在那个接口上有一个对象,唉:

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

对象一也是 ComVisible(true),在一个单独的程序集中,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)。

【问题讨论】:

    标签: c# c++ com com-interop


    【解决方案1】:

    你可以只导入两个程序集,应该就是这样:

    组装1:

    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")]
    

    组装2:

    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;
    }
    

    顺便说一句,你想要raw_interfaces_only 有什么具体原因吗?没有它会更容易,更安全:

    ClassLibrary2::IInterface1Ptr i1;
    i1.CreateInstance(__uuidof(ClassLibrary2::Interface1));
    
    auto o1 = i1->Object1;
    auto bstr = o1->MyProperty;
    

    【讨论】:

      猜你喜欢
      • 2017-07-20
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 2010-11-26
      • 2010-12-12
      相关资源
      最近更新 更多