【问题标题】:Invoking COM Properties and Methods调用 COM 属性和方法
【发布时间】:2011-05-13 15:15:30
【问题描述】:

我正在尝试动态创建 COM 对象、调用 COM 方法并设置 COM 属性。 COM 类是一个 VB6 ActiveX DLL。该实现与本页http://msdn.microsoft.com/en-us/library/ms973800.aspx中的VB6代码完全相同。

简而言之,项目是PhysServer,类名是Temperature,它有两个属性CelsiusFahrenheit和两个方法GetCelsius()GetFahrenheit()

我已经运行regsvr32 将ActiveX DLL 注册到计算机。 ProgID 是PhysServer.Temperature

我有三个代码块

代码块 1(有效)

Option Explicit Off
Option Strict Off
...
Dim objType = Type.GetTypeFromProgID("PhysServer.Temperature")
Dim comObj = Activator.CreateInstance(objType)
comObj.Celsius = 100
Dim f As Double = comObj.GetFahrenheit()
Console.WriteLine(f) ' shows 212

代码块 2(有效)

Option Explicit On
Option Strict On
...
Dim objType = Type.GetTypeFromProgID("PhysServer.Temperature")
Dim comObj = Activator.CreateInstance(objType)
Microsoft.VisualBasic.CallByName(comObj, "Celsius", CallType.Let, 100)
Dim f As Double = CDbl(Microsoft.VisualBasic.CallByName(comObj, "GetFahrenheit", CallType.Method, Nothing))
Console.WriteLine(f) ' shows 212

代码块 3(不起作用)

Option Explicit On
Option Strict On
...
Dim objType = Type.GetTypeFromProgID("PhysServer.Temperature")
Dim comObj = Activator.CreateInstance(objType)
Dim f As Double = CDbl(objType.InvokeMember("GetFahrenheit", Reflection.BindingFlags.InvokeMethod, Nothing, comObj, Nothing))
Console.WriteLine(f) ' shows the default value of GetFahrenheit '
objType.InvokeMember("Celsius", Reflection.BindingFlags.SetField Or Reflection.BindingFlags.InvokeMethod, Nothing, comObj, New Object() {100}) ' throws exception: Number of parameters specified does not match the expected number '
f = CDbl(objType.InvokeMember("GetFahrenheit", Reflection.BindingFlags.InvokeMethod, Nothing, comObj, Nothing))
Console.WriteLine(f)

我了解代码块 1 和代码块 2。但是,我如何使用代码块 3 之类的反射设置 COM 对象?由于某些原因,我无法使用代码块 1 和代码块 2。所以唯一的方法是代码块 3……但它不起作用。

有人知道Code Block 3 的解决方案吗?谢谢!

【问题讨论】:

    标签: vb.net com invoke


    【解决方案1】:

    试试这个:

    objType.InvokeMember("Celsius", Reflection.BindingFlags.SetProperty Or ...
    

    而不是 SetField。

    comObj 是一个 Runtime-Callable Wrapper,Celsius 将是它的一个属性,而不是一个字段。

    您也可能需要指定BindingFlags.Instance 标志。

    【讨论】:

    • 这不是 RCW,他使用的是后期绑定。天知道为什么。
    • 谢谢各位...我在互联网上找到了解决方案。请阅读我的回答。
    • @Hans Passant : 当然,即使使用 IDispatch,它仍然是 RCW?
    • 不是。不需要互操作库,因此不会/不能生成 RCW。 IDispatch 就足够了。
    • 谢谢克里斯。对上一篇文章感到抱歉。我已将您的回复标记为解决方案。并且应该删除InvokeMethod
    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 2010-10-14
    • 2014-03-13
    • 2013-10-15
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多