在.Net中实例化具有VB6定义的COM接口的.Net对象会抛出TypeLoadException

时间:2016-03-18 10:09:31

标签: c# .net vb6 com-interop

我在一个名为IODevice的VB6 COM DLL中定义了一个COM接口。

Public Sub Connect(ByVal Device As String)
End Sub

Public Sub Disconnect()
End Sub

我有一个导入并实现此接口的.Net类。

[ComVisible(true)]
[Guid("92255E76-6C1A-333F-883C-6EE9FD9937BA")]
public class COMInterface : ICIO.IODevice {
    public COMInterface() {
        // Do nothing
    }

    public void Connect(string deviceString) {
        // Do stuff
    }

    public void Disconnect() {
        // Undo stuff
    }
}

此对象运行良好,可以使用CreateObject()在VB6中创建并引用为IODevice接口。

我现在正在将调用代码移动到.Net并使用Activator.CreateInstance

Type deviceType = Type.GetTypeFromProgID(typeProgID, true);
object instance = Activator.CreateInstance(deviceType);

同样,这段代码工作正常,将实例化并使用任何实现IODevice的VB6类。当我尝试加载实现该接口的.Net对象时出现问题。

System.TypeLoadException: Retrieving the COM class factory for component with CLSID {92255E76-6C1A-333F-883C-6EE9FD9937BA} failed due to the following error: 80131522. 
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) 
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) 
   at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) 
   at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
   at System.Activator.CreateInstance(Type type) 
   at iCode.Console.IOEngine.Wrappers.ICIO.IODeviceWrapper.ConnectDevice() 

如果我从COMInterface中删除该接口,那么该对象可以被实例化,但缺少允许我使用其任何成员的接口。

public class COMInterface /*: ICIO.IODevice*/ {

所有库都设置为目标x86和.Net 2,但更改这些不会影响结果。
我还确认托管IODevice接口的VB6库及其互操作DLL与包含COMInterface的程序集位于同一文件夹中。

我缺少什么,未能做什么以及如何在保持IODevice界面的同时从.Net创建此对象的实例?

(示例代码从大型代码库中删除,但我会尝试创建一个最小的示例。)

1 个答案:

答案 0 :(得分:2)

这是由于运行时无法解析原始IODevice接口使用的类型(在本例中为VBA.vbVarType)。

当我尝试加载程序集并直接使用反射获取类型时,我收到了以下异常:

System.TypeLoadException: Method 'get_PortType' in type 'NetLibrary.COMInterface' does not have an implementation.
   at System.Reflection.Assembly._GetType(String name, Boolean throwOnError, Boolean ignoreCase)
   at System.Reflection.Assembly.GetType(String name)
   at InstantiationTest.Program.Main(String[] args)

msvbvm60.dll添加COM引用允许直接加载此类型,反过来,原始代码能够创建该对象的实例。