这是一个测试代码:
Public Class Class2
Public GoodName as String
Public Function someFunction ()
End Function
End Class
Public Class Class1
Public Enum ENUM_VAL1_
abc = 1
def = 2
End Enum
Public Enum ERROR_VAL1_
yhn = 1
ujm = 2
End Enum
Public Function fun1(byval _enumArg1 as ENUM_VAL1_,
byval _stringArg as String,
byref _classArg Class2) as ERROR_VAL1_
... SOMETHING HERE
return something
End Function
End Class
和测试
Dim asm As Assembly = Assembly.LoadFrom(<the source>)
If asm Is Nothing Then Return Nothing
Dim typ As Type = asm.GetType(<namespace>.<class1>)
If typ Is Nothing Then Return Nothing
Dim obj As Object = Activator.CreateInstance(typ)
If obj Is Nothing Then Return Nothing
Dim arg As Object() = New Object() {ENUM_VAL1_.abc, "qazxsw", New Class2}
Dim res As Object = typ.InvokeMember( _
"fun1", _
BindingFlags.[Default] Or BindingFlags.InvokeMethod, _
Nothing, _
obj, _
arg)
[ Dim res As Object = typ.InvokeMember( _
"fun1", _
BindingFlags.[Default] Or BindingFlags.InvokeMethod, _
Nothing, _
obj, _
arg)
] 返回错误:function '[fullname]' not found.
然后我意识到 fun1 签名与我的调用不同(即使枚举值是整数)。我做了一些研究,发现当目标程序集上的属性或函数具有与标准类型不同的参数时如何实现反射的“一些”示例。但我成功地将这些样本“概念”转化为我的需要。
所以,在这里我放了一些带有虚拟枚举类型的虚拟类,只是为了指出问题的根源。
原始代码是关于 windows 防火墙/端口 (win7/xp/vista) 的,其中有许多枚举值,包括来自 firewallApi.dll 和 Hnetcfg.dll 的类型。
我遇到的问题是我不能“InvokeMember”(也是“SetProperties”和“SetProperties”)使用说:
Dim args As Object() = New Object() {"SQL", 6, "1433", 1}
我的程序集函数具有这些参数类型。
Public Function PortExists( _
ByVal _ruleName As String, _
ByVal _protocol As NET_FW_IP_PROTOCOL_, _
ByVal _remotePorts As String, _
ByVal _direction As NET_FW_RULE_DIRECTION_ _
) As FW_ERROR_CODE
好的,为简化起见,我制作了自己的枚举类型(无需安装额外的库)
Public Function PortExists( _
ByVal _ruleName As String, _
ByVal _protocol As FW_IP_PROTOCOL, _
ByVal _remotePorts As String, _
ByVal _direction As FW_RULE_DIRECTION _
) As FW_ERROR_CODE
不知何故,参数“6”和“1”应该分别转换为FW_IP_PROTOCOL
和FW_RULE_DIRECTION
类型......
我不知道怎么办!