Почему это вызывает исключение InvalidClassCast?

По определенным причинам я должен предоставить вручную написанные вызываемые оболочки во время выполнения для ряда COM-компонентов, предлагаемых моим магазином.

Это определение интерфейса для компонента A:

[ComImport, Guid("02922621-2EAE-4442-8A0A-C1C3CD886027")]
public interface IProdistLogging
{
  [DispId(1000)]
  IProdistLoggingHierarchy CreateHierarchy ([MarshalAs(UnmanagedType.BStr)] string type, object configuration);
}

Это определение интерфейса для компонента B:

[ComImport, Guid("8D841E5C-F25B-4C12-B03A-70A899B3A32E")]
public interface ISts
{
  [DispId(1001)]
  IProdistLoggingHierarchy Logging { get; set; }

  [DispId(1000)]
  IStsSession CreateSession ();
}

Это определение интерфейса для компонента C:

[ComImport, Guid("13385FC6-2618-4830-A3A9-703398AA5A0B")]
public interface IStsRsfn
{
  [DispId(1000)]
  ISts Sts { get; set; }

  [DispId(1010)]
  IStsRsfnSession CreateSession();
}

Теперь следующая тестовая программа завершается с InvalidCastException:

public static void Main (string[] args)
{
  IProdistLogging logging = (IProdistLogging)System.Activator.CreateInstance(Type.GetTypeFromProgID("prodist.logging.Logging.5.4"));
  IProdistLoggingHierarchy loggingHierarchy = logging.CreateHierarchy("log4cxx", null);
  ISts sts = (ISts)System.Activator.CreateInstance(Type.GetTypeFromProgID("prodist.sts.Sts.5.4"));
  sts.Logging = loggingHierarchy;
  IStsRsfn rsfn = (IStsRsfn)System.Activator.CreateInstance(Type.GetTypeFromProgID("prodist.sts.rsfn.StsRsfn.5.4"));

  // The following statement raises an InvalidCastException
  // with message "Specified cast is not valid"
  rsfn.Sts = sts;

  IStsRsfnSession session = rsfn.CreateSession();
  return;
}

С чего бы это?

Редактировать 1: это результат toString() для объекта исключения:

System.InvalidCastException: Specified cast is not valid.
   at prodist.sts.rsfn.IStsRsfn.set_Sts(ISts value)
   at sandbox.Program.Main(String[] args) in (...)

1 ответ

Решение

С тех пор мы обнаружили недостающую информацию, которая объясняет вышеуказанные симптомы: фактическое определение IDL для интерфейса.

Проблемная оболочка.NET не включала все методы соответствующего интерфейса, так что порядковый индекс для свойства Sts put в IDL и.NET не был одинаковым - даже если значение DispId является правильным.

После того, как мы обновили оболочку.NET, чтобы полностью отразить все методы из определения IDL - так, чтобы у каждого метода был тот же порядковый индекс, что и у другого - все работало.

Программист предположил, что методы были "смещены" в соответствии со значением атрибута DispId, но кажется, что они "смещены" на их фактическую позицию в списке методов от первого до последнего. Это подразумевает, что недопустимо предоставлять частичные обертки для интерфейсов - обертки, которые опускают определенные методы.

Другие вопросы по тегам