我有一个遗留的VB6函数,我想从C#中调用它。
异常情况如下:
我尝试将
它会抛出以下类似但不同的异常:
有趣的是,如果我在C#或VB.NET示例代码中更改调用,使用
我还尝试使用
最后,我尝试了以下VB.NET代码:
它会抛出以下异常:
Public Function CreateMiscRepayment(ByRef objMiscRepayment As MiscRepayment) As Variant
' Code that sets objMiscRepayment here
End Function
我在使用以下C#代码时出现异常:
dynamic vb6ComObject = Activator.CreateInstance(Type.GetTypeFromProgID(progId));
dynamic miscRepayment = null;
dynamic result = vb6ComObject.CreateMiscRepayment(ref miscRepayment);
异常情况如下:
System.ArgumentException: Could not convert argument 0 for call to CreateMiscRepayment.
at System.Dynamic.ComRuntimeHelpers.CheckThrowException(Int32 hresult, ExcepInfo& excepInfo, UInt32 argErr, String message)
at CallSite.Target(Closure , CallSite , ComObject , Object& )
at CallSite.Target(Closure , CallSite , ComObject , Object& )
at CallSite.Target(Closure , CallSite , Object , Object& )
at CallSite.Target(Closure , CallSite , Object , Object& )
Application\ApplicationClasses.cs(65,0): at ApplicationClasses.CanInstantiateMiscRepayment()
我尝试将
ref
改成out
,但是得到了相同的错误。如果我省略ref
,方法就会执行而不出错,但是miscRepayment
仍然是null,而不是包含应该传递出去的对象。
更新
我尝试了一些其他方式,包括使用VB.NET(因为它一直比C#更加友好)。
以下是VB.NET代码:
Dim vb6ComObject = Activator.CreateInstance(System.Type.GetTypeFromProgID(progId))
Dim miscRepayment = Nothing
Dim result = vb6ComObject.CreateMiscRepayment(miscRepayment)
它会抛出以下类似但不同的异常:
System.Runtime.InteropServices.COMException: Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
UnitTest1.vb(19,0): at TestProject1.UnitTest1.TestMethod1()
有趣的是,如果我在C#或VB.NET示例代码中更改调用,使用
null
/Nothing
而不是miscRepayment
,则代码将执行而不会抛出异常。我甚至在VB6 COM对象的代码中设置了断点,并确认代码已经正确地在那一端执行。显然,将miscRepayment
参数设置为null
/Nothing
后,.NET就没有办法接收创建的对象。问题必须与参数的封送有关。我还尝试使用
Type.InvokeMember
和一个标记miscRepayment
为ref
参数的ParameterModifier
参数,但会出现以下异常:System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))
--- End of inner exception stack trace ---
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
UnitTest1.vb(18,0): at TestProject1.UnitTest1.TestMethod1()
最后,我尝试了以下VB.NET代码:
Dim vb6ComObject = Activator.CreateInstance(System.Type.GetTypeFromProgID(progId))
Dim args(0) As Object
Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(vb6ComObject, type, "CreateMiscRepayment", args, Nothing, New Boolean() {True})
它会抛出以下异常:
System.Runtime.InteropServices.COMException: Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))
at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn)
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
UnitTest1.vb(17,0): at TestProject1.UnitTest1.TestMethod1()
在所有抛出异常的代码中,VB6 COM对象从未被调用。当尝试传递ref
参数时,COM交互操作代码可能会出现问题。
在我的谷歌搜索中,我发现了一些使用Type.InvokeMember
的示例,但是ref
参数总是针对简单类型,如整数和字符串。
dynamic
改为object
,但仍然抛出相同的异常。不太确定你最后一句话的意思。 - John Millstype.GetMethod("CreateMiscRepayment")
返回 null。type.GetMethods()
返回 7 个方法,但这些是 MarshalByRefObject 上的公共方法。 - John MillsActivator.CreateInstance(Type.GetTypeFromProgID(progId)
е®ћдѕ‹еЊ–дє†vb6ComObject
гЂ‚ж€‘жІЎжњ‰еј•з”Ёд»»дЅ•дє’ж“ЌдЅњзЁ‹еєЏй›†пј›еёЊжњ›дЅїз”ЁеЉЁжЂЃж–№ејЏеЏЇд»ҐйЃїе…Ќиї™ж ·еЃљгЂ‚ - John MillsGetTypeFromProgID(progId)
返回的类型,看看是否包含这些方法。 - John Mills