Click here to Skip to main content
15,891,951 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an assembly written in C# that is exposing some functionality via COM (for use by legacy C++ code). In particular, there are two classes (ThingOne and ThingTwo) that each implement ComVisible interfaces.
Simplifying:
C#
[ComVisible(true), Guid("...."), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IThingOne
{
  [DispId(1)]
  IThingTwo FindByName(string name);
  [DispId(2)]
  IThingTwo[] FindMatchesByValue(double value);
}

[ComVisible(true), Guid("...."), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IThingTwo
{
  [DispId(1)]
  string Name { get; }
  [DispId(2)]
  double Value { get; }
  [DispId(3)]
  double ValueWindow { get; }
}

The Type Library view of the IThingOne looks like:
interface IThingOne : IDispatch {
    [id(0x00000001)]
    HRESULT FindByName(
                    [in] BSTR name,
                    [out, retval] IThingTwo** pRetVal);
    [id(0x00000002)]
    HRESULT FindMatchesByValue(
                    [in] double value,
                    [out, retval] SAFEARRAY(IThingTwo*)* pRetVal);
};

The ThingOne class has a collection of ThingTwo class instances. When accessed via COM, the FindByName method correctly returns a COM IThingTwo interface pointer to a ThingTwo class instance.
However, the FindMatchesByValue seems to return a valid SAFEARRAY but the contents of that are not valid COM IThingTwo interface pointers to ThingTwo class instances.

Are there any tricks to doing this kind of thing?

What I have tried:

This is essentially what's in the two IThingOne methods:
C#
IThingTwo IThingOne.FindByName(string name)
{
  return ThingTwoCollection.FirstOrDefault(t2 => t2.Name == name);
}

IThingTwo[] IThingOne.FindByValue(double value)
{
  var found = ThingTwoCollection.Where(t2 => t2.InRange(value));
  return found.Cast<IThingTwo>().ToArray();
}

// ThingTwo has an InRange predicate that tests the value against the range.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900