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:
[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:
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();
}