2015-02-04 1 views
0

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

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

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

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

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

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

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

[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; 
} 

Зачем это было?

Edit 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 (...) 
+0

Вам необходимо отправить сообщение * full * exception. Доллар до пончиков, сервер COM не имеет прокси. Попробуйте поместить [STAThread] в свой метод Main(), чтобы он не требовался. Это неверно, но вы, по крайней мере, устраните эту возможную проблему. –

ответ

0

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

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

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

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