Matt T Heffron Ответов: 0

Возвращает массив из COM-интерфейсов от c#


У меня есть сборка, написанная на C#, которая предоставляет некоторую функциональность через COM (для использования устаревшим кодом C++). В частности, существует два класса (ThingOne и ThingTwo) что каждый реализует ComVisible межфазные границы.
Упрощающий:
[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; }
}

Представление библиотеки типов IThingOne выглядит как:
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);
};

То ThingOne класс имеет коллекцию ThingTwo экземпляр класса. При доступе через COM FindByName метод корректно возвращает COM IThingTwo указатель на интерфейс ThingTwo экземпляр класса.
Тем не менее, FindMatchesByValue кажется чтобы вернуть действительный SAFEARRAY но содержание этого не является действительным. IThingTwo указатели интерфейса на ThingTwo экземпляр класса.

Есть ли какие-нибудь хитрости, чтобы делать такие вещи?

Что я уже пробовал:

Это по существу что в этих двух IThingOne методы:
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.

0 Ответов