0

So I've got an interface (IInterface1) exposed as ComVisible(true), ClassInterfaceType(ClassInterfaceType.None).

I have an object on that Interface, ala:

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

Object one is also ComVisible(true), is in a separate assembly, ClassInterfaceType(ClassInterfaceType.None), and looks like so:

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

In C# still, I've got the following class:

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

From unmanaged C++, how would I access Interface1.Object1.MyProperty? I'm importing the TLH raw_interfaces_only, can CreateInstance my Interface1 class, and access Object1. If I try to access MyProperty on Object1, I get a "pointer to incomplete class type not allowed".

The c++ code looks like:

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

hrRetval = interface1ptr.get_Object1(&object1);

This is where I'm stuck:

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

Appreciate any pointers (har har).

John
  • 921
  • 1
  • 9
  • 24

1 Answers1

0

You could just import both assemblies, that should be it:

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, is there some specific reason why you want raw_interfaces_only? It would be easier and safer without it:

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

auto o1 = i1->Object1;
auto bstr = o1->MyProperty;
Nikolay
  • 10,752
  • 2
  • 23
  • 51