方法调用失败
问题描述:
背景:方法调用失败
我已经写在ASP(VBScript)的遗留应用程序,它调用用VB6 COM组件。我们正在分阶段进行升级,并且需要先将COM组件更新到.NET,同时保持与ASP的互操作性。
情况:
- 我创建了一个样本.NET类和使用各种属性作为每MSDN文档它暴露给COM系统
- 我能够实例化类
- 我能拨打所需类别的方法
问题:
- 参数值不会发送到COM方法。例如所有数值类型在方法内都有值0;所有引用类型在方法内都有空值。文字字符串正确地传递给方法。但是,字符串变量不传递。
- 与返回值相同的问题。无论方法返回的值是多少,ASP上的变量都具有默认值(0或null,视情况而定)。
COM代码
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
备用COM代码
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
Public Class Class1
'Inherits ServicedComponent
'Implements IClass1
Public Sub New()
' needed for COM
End Sub
Private Const LogMessageFormat As String = "[{0:s}] Input: {1}, {2}" + vbCrLf
Public Function Triple(csinput As String, nInput As Integer) As Integer 'Implements IClass1.Triple
IO.File.AppendAllText("C:\TestCOM.Class1_Triple.log",
String.Format(LogMessageFormat, Date.Now, if(csinput isnot Nothing, csinput, "**NULL**"), nInput))
Return 97
End Function
End Class
ASP代码
dim testNETCOM
set testNETCOM = Server.CreateObject("TESTCOM.Class1")
' ** use this to check if there was any error during instantiation
If Err.Number <> 0 Then
Response.Redirect("http://"&Err.Description&"/")
'Response.Write (Err.Description& "<br><br>")
else
'Response.Redirect("http://no-error/")
End If
' ** use this to check if object is actually instantiated
if testNETCOM is nothing then
Response.Redirect("http://no-com/")
else
'Response.Redirect("http://yes-com/")
end if
dim nInput
set nInput = 41
dim nOutput
set nOutput = -1
set nOutput = CLng(testNETCOM.Triple("test message")) ' this string is received in the method
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this string is not received in the method
' ** use this to check if return value is what we expected
if nOutput <> 0 then
Response.Redirect("http://test/")
else
Response.Redirect("http://notest/") ''' **this happens**
end if
答
给任一一个尝试:
<ComVisible(True)>
<Guid("79571A9D-2345-48D9-8F86-7F6761A97DBA")>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IClass1
Function Triple(ByVal input As String) As Integer
End Interface
<ComVisible(True)>
<Guid("E26FE8A0-8AC7-4824-9776-30ECDD473AA3")>
<ProgId("TESTCOM.Class1")>
<ClassInterface(ClassInterfaceType.None)>
Public Class Class1
Inherits ServicedComponent
Implements IClass1
Public Sub New()
' needed for COM
End Sub
Public Function Triple(input As String) As Integer Implements IClass1.Triple
IO.File.WriteAllText("C:\TestCOM.Class1_Triple.log", String.Format("[{0:s}] Input: {1}", Date.Now, input)) ''' this file is updated; so I know method is being called.
Return 97
End Function
End Class
或者:
<ComVisible(True)>
<ProgId("TESTCOM.Class1")>
<ComClass("E26FE8A0-8AC7-4824-9776-30ECDD473AA3", "79571A9D-2345-48D9-8F86-7F6761A97DBA")>
Public Class Class1
'Inherits ServicedComponent
'Implements IClass1
Public Sub New()
' needed for COM
End Sub
Private Const LogMessageFormat As String = "[{0:s}] Input: {1}, {2}" + vbCrLf
Public Function Triple(csinput As String, nInput As Integer) As Integer 'Implements IClass1.Triple
IO.File.AppendAllText("C:\TestCOM.Class1_Triple.log",
String.Format(LogMessageFormat, Date.Now, if(csinput isnot Nothing, csinput, "**NULL**"), nInput))
Return 97
End Function
End Class
+0
仍然没有运气,尝试其他一些方法来获得更多信息 – bigbyte
答
的问题是在ASP
- 对于简单数据类型的语法,不使用 '设置'
- 对于物体,请使用'set'
因为我正在使用简单类型的set,所以在赋值过程中出现错误,并且null/nothing/empty变量的值。
set nInput = 41 ' this is wrong
nInput = 41 ' this is right
set nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this is wrong
nOutput = CLng(testNETCOM.Triple(CStr(nInput))) ' this is right
请注意,VB6 Long类型是.Net类型System.Int32或VB类型的整型。此外,如果应用[ComClassAttribute](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.comclassattribute),则VB.Net编译器将帮助您创建COM类,而无需构建接口(v = vs.110).aspx#例子)。 – TnTinMn
关于不同数据类型的好处。我更新了代码,但问题仍然存在。 – bigbyte
我的主要观点是,让编译器把你的类暴露给COM,因为我相信这些东西比我更多。无论如何,我认为你所需要做的就是为你的班级和界面应用一个独特的属性。使用VS工具来简化它。工具菜单 - >创建GUID->选择格式6(在VS 2013下) - >复制。然后粘贴到类上,重复该界面。 – TnTinMn