2017-02-16 126 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