2017-02-16 81 views
1

背景方法调用失败

我已经写在ASP(VBScript)的遗留应用程序,它调用用VB6 COM组件。我们正在分阶段进行升级,并且需要先将COM组件更新到.NET,同时保持与ASP的互操作性。

情况

  1. 我创建了一个样本.NET类和使用各种属性作为每MSDN文档它暴露给COM系统
  2. 我能够实例化类
  3. 我能拨打所需类别的方法

问题

  1. 参数值不会发送到COM方法。例如所有数值类型在方法内都有值0;所有引用类型在方法内都有空值。文字字符串正确地传递给方法。但是,字符串变量不传递。
  2. 与返回值相同的问题。无论方法返回的值是多少,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 
+0

请注意,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

+0

关于不同数据类型的好处。我更新了代码,但问题仍然存在。 – bigbyte

+0

我的主要观点是,让编译器把你的类暴露给COM,因为我相信这些东西比我更多。无论如何,我认为你所需要做的就是为你的班级和界面应用一个独特的属性。使用VS工具来简化它。工具菜单 - >创建GUID->选择格式6(在VS 2013下) - >复制。然后粘贴到类上,重复该界面。 – TnTinMn

回答

0

给任一一个尝试:

<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

2

的问题是在ASP

  1. 对于简单数据类型的语法,不使用 '设置'
  2. 对于物体,请使用'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