[英]Why would this raise an InvalidClassCast exception?
For certain reasons, I must provide manually written runtime callable wrappers for a number of COM components offered by my shop. 由于某些原因,我必须为商店提供的许多COM组件提供手动编写的运行时可调用包装器。
This is the interface definition for component A: 这是组件A的接口定义:
[ComImport, Guid("02922621-2EAE-4442-8A0A-C1C3CD886027")]
public interface IProdistLogging
{
[DispId(1000)]
IProdistLoggingHierarchy CreateHierarchy ([MarshalAs(UnmanagedType.BStr)] string type, object configuration);
}
This is the interface definition for component B: 这是组件B的接口定义:
[ComImport, Guid("8D841E5C-F25B-4C12-B03A-70A899B3A32E")]
public interface ISts
{
[DispId(1001)]
IProdistLoggingHierarchy Logging { get; set; }
[DispId(1000)]
IStsSession CreateSession ();
}
This is the interface definition for component C: 这是组件C的接口定义:
[ComImport, Guid("13385FC6-2618-4830-A3A9-703398AA5A0B")]
public interface IStsRsfn
{
[DispId(1000)]
ISts Sts { get; set; }
[DispId(1010)]
IStsRsfnSession CreateSession();
}
Now, the following test program terminates with an InvalidCastException: 现在,以下测试程序以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;
}
Why would this be? 为什么会这样呢?
Edit 1: this is the result of toString() on the exception object: 编辑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 (...)
We have since discovered the missing information which explains the above symptoms: the actual IDL definition for the interface. 此后,我们发现了缺少的信息,这些信息解释了上述症状:接口的实际IDL定义。
The problematic .NET wrapper did not include all methods of the corresponding interface, such that the ordinal index for the Sts put property in IDL and .NET was not the same -- even though the DispId value is correct. 有问题的.NET包装器没有包括相应接口的所有方法,因此IDL和.NET中Sts put属性的序号索引不相同-即使DispId值正确。
After we updated the .NET wrapper to completely reflect all methods from the IDL definition -- such that each method was at the same ordinal index as the other -- everything worked. 在更新.NET包装器以完全反映IDL定义中的所有方法之后-每种方法与另一方法具有相同的序号索引-一切正常。
The programmer assumed that methods were "offset" according with the value of the DispId attribute, but it seems they are "offset" by their actual position in the list of methods from first to last. 程序员假定方法是根据DispId属性的值“偏移”的,但是似乎它们在方法列表中从头到尾的实际位置是“偏移”的。 This implies it is not lawful to provider partial wrappers for interfaces -- wrappers which omit certain methods.
这意味着为接口提供提供者部分包装是不合法的-省略某些方法的包装。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.