当具有ref参数时,如何使用动态调用C#中的VB6 COM对象?
我有以下传统的VB6功能,我想从C#调用.
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,Object,Object& ) ApplicationApplicationClasses.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和ParameterModifier参数,该参数将miscRepayment标记为ref参数,但得到以下异常: 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,Boolean[] byrefModifiers,Int32 culture,String[] namedParameters) at System.RuntimeType.InvokeMember(String name,BindingFlags bindingFlags,Binder binder,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,Boolean[] CopyBack,Boolean IgnoreReturn) at Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(Object o,Boolean[] CopyBack) UnitTest1.vb(17,0): at TestProject1.UnitTest1.TestMethod1() 使用抛出异常的所有代码,永远不会调用VB6 COM对象.尝试编组ref参数时,COM互操作代码必须窒息. 在我的Google搜索中,我遇到了一些使用Type.InvokeMember的示例,但ref参数始终用于简单类型,如整数和字符串. 解决方法
在.NET中,似乎没有办法在COM对象上调用一个带有复杂类型的ref参数的方法.
我和微软有filed a bug.如果此问题也影响您,请投票it. 2013年4月30日更新 有一条评论来自微软的错误报告说它已被修复.但是没有提到哪个版本的.NET受到了影响. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |