none
[vb.net2005]錯誤訊息 類型不相符。 (發生例外狀況於 HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)) RRS feed

  • 問題

  • 請問一下各位前輩

    我在程式中

            Dim myMeter
            Select Case Meter
                Case 1
                    myMeter = New TD.TD1_IO
                Case 2
                    myMeter = New TD.TD2_IO
            End Select
            Dim I As Integer = 1
            Dim strData As String = ""
            myMeter.IO_ReadStorageData_Time(I, strData)

    其中TD.TD1_IO、TD.TD2_IO是用vb開發的元件

    myMeter.IO_ReadStorageData_Time(I, strData)在傳參數時是以byRef

    執行時會發生問題

    System.Runtime.InteropServices.COMException 未處理
      ErrorCode=-2147352571
      Message="類型不相符。 (發生例外狀況於 HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
      Source="Microsoft.VisualBasic"
      StackTrace:
           於 Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
           於 Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
           於 Taidoc.DownLoadDataClass.getLastNRecord(Int16 N) 於 D:\VB2005程式\DrT\Taidoc\Taidoc\DownLoadDataClass.vb: 行 158
           於 Taidoc.DownLoadData.Button1_Click(Object sender, EventArgs e) 於 D:\VB2005程式\DrT\Taidoc\Taidoc\DownLoadData.vb: 行 16
           於 System.Windows.Forms.Control.OnClick(EventArgs e)
           於 System.Windows.Forms.Button.OnClick(EventArgs e)
           於 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           於 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           於 System.Windows.Forms.Control.WndProc(Message& m)
           於 System.Windows.Forms.ButtonBase.WndProc(Message& m)
           於 System.Windows.Forms.Button.WndProc(Message& m)
           於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           於 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           於 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           於 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           於 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           於 System.Windows.Forms.Application.Run(ApplicationContext context)
           於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           於 Taidoc.My.MyApplication.Main(String[] Args) 於 17d14f5c-a337-4978-8281-53493378c1071.vb: 行 81
           於 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           於 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           於 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           於 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           於 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           於 System.Threading.ThreadHelper.ThreadStart()

    但是TD.TD1_IO中有很多方法,只有參數是用byref傳時才會有問題

    而且如果我改寫成

            Dim myMeter as New TD.TD1_IO
            Dim I As Integer
            Dim strData As String = ""
            myMeter.IO_ReadStorageData_Time(I, strData)

    竟然就沒問題了

    到底是為啥???

    >///<......因為我必須依使用者輸入的值來決定要用哪種

     

     

    2006年10月18日 上午 09:40

解答

  • 應該是自動封送的問題。

    請把原型的引數型別宣告找出來,用型別轉換函數轉換成強型別。

    用提前連結會自動轉,用延後連結必要時需要手動轉。

    在 OWC 也常發生。

    型別轉換函數:CInt, CLng, CStr, ... 等。

    還有,.Net 的記憶體處理方式跟 VB6 用的 oleaut32.dll 略有不同,沒事別隨便用 ByRef ,用函數來回傳還比較保險,不然就用 VBNET 重新改寫原先元件,變成 .Net Managed DLL ,不要用 COM DLL (ActiveX DLL)

    2006年10月18日 下午 02:41
    版主
  • 如果元件不是你開發的,你可以試試看:

    1. 在 VS2005 下 Ctrl+Alt+J 開啟物件瀏覽器

    2. 瀏覽下拉選 編輯自訂元件 ,把你需要用的 COM DLL 拉進來

    3. 選擇你用的元件與方法,觀看右下方的宣告。

    Dim xxx As New MyType

    這是對 xxx 變數宣告為提前連結,提前連結時,自動封送可以判別型別而做強制轉換。

    Dim xxx As Object
    xxx = New MyType

    這是對 xxx 變數做延後連結,延後連結時,自動封送可能無法判別引數而自動封送轉換。

    CType 也是強型別轉換函數,網路上有建議轉換 xxx 為強型別

    xxx = CType(xxx, MyType)

    不過我自己用的有問題,所以我通常針對引數做手動強型別轉換

    xxx.Method(CShort(1234), CInt(2345))

    注意,用強型別轉換函數將無法使用 ByRef 。例如:變數 a 在記憶體位置 x ,用強型別轉換函數轉換後,會得到暫存變數 b 在記憶體位置 y ,引數是傳 y 位置過去,並非是 x 位置,所以變數 a 並不會被置換,而變數 b 卻會被釋放,所以對於 ByRef 會遺失。

    2006年10月18日 下午 03:26
    版主

所有回覆

  • 應該是自動封送的問題。

    請把原型的引數型別宣告找出來,用型別轉換函數轉換成強型別。

    用提前連結會自動轉,用延後連結必要時需要手動轉。

    在 OWC 也常發生。

    型別轉換函數:CInt, CLng, CStr, ... 等。

    還有,.Net 的記憶體處理方式跟 VB6 用的 oleaut32.dll 略有不同,沒事別隨便用 ByRef ,用函數來回傳還比較保險,不然就用 VBNET 重新改寫原先元件,變成 .Net Managed DLL ,不要用 COM DLL (ActiveX DLL)

    2006年10月18日 下午 02:41
    版主
  •  璉璉 寫信:

    應該是自動封送的問題。

    請把原型的引數型別宣告找出來,用型別轉換函數轉換成強型別。

    用提前連結會自動轉,用延後連結必要時需要手動轉。

    在 OWC 也常發生。

    型別轉換函數:CInt, CLng, CStr, ... 等。

    還有,.Net 的記憶體處理方式跟 VB6 用的 oleaut32.dll 略有不同,沒事別隨便用 ByRef ,用函數來回傳還比較保險,不然就用 VBNET 重新改寫原先元件,變成 .Net Managed DLL ,不要用 COM DLL (ActiveX DLL)

    您好

    謝謝您的回答

    但是小的愚昧

    請問

    "請把原型的引數型別宣告找出來,用型別轉換函數轉換成強型別"-------->這句是什麼意思丫?

    是要改元件裡面的程式嗎??

    因為元件不是我開發的.....所以這點有點小困難

    請問還有別種方法嗎?

    謝謝您的幫忙~~~

    2006年10月18日 下午 03:09
  • 如果元件不是你開發的,你可以試試看:

    1. 在 VS2005 下 Ctrl+Alt+J 開啟物件瀏覽器

    2. 瀏覽下拉選 編輯自訂元件 ,把你需要用的 COM DLL 拉進來

    3. 選擇你用的元件與方法,觀看右下方的宣告。

    Dim xxx As New MyType

    這是對 xxx 變數宣告為提前連結,提前連結時,自動封送可以判別型別而做強制轉換。

    Dim xxx As Object
    xxx = New MyType

    這是對 xxx 變數做延後連結,延後連結時,自動封送可能無法判別引數而自動封送轉換。

    CType 也是強型別轉換函數,網路上有建議轉換 xxx 為強型別

    xxx = CType(xxx, MyType)

    不過我自己用的有問題,所以我通常針對引數做手動強型別轉換

    xxx.Method(CShort(1234), CInt(2345))

    注意,用強型別轉換函數將無法使用 ByRef 。例如:變數 a 在記憶體位置 x ,用強型別轉換函數轉換後,會得到暫存變數 b 在記憶體位置 y ,引數是傳 y 位置過去,並非是 x 位置,所以變數 a 並不會被置換,而變數 b 卻會被釋放,所以對於 ByRef 會遺失。

    2006年10月18日 下午 03:26
    版主
  •  璉璉 寫信:

    如果元件不是你開發的,你可以試試看:

    1. 在 VS2005 下 Ctrl+Alt+J 開啟物件瀏覽器

    2. 瀏覽下拉選 編輯自訂元件 ,把你需要用的 COM DLL 拉進來

    3. 選擇你用的元件與方法,觀看右下方的宣告。

    Dim xxx As New MyType

    這是對 xxx 變數宣告為提前連結,提前連結時,自動封送可以判別型別而做強制轉換。

    Dim xxx As Object
    xxx = New MyType

    這是對 xxx 變數做延後連結,延後連結時,自動封送可能無法判別引數而自動封送轉換。

    CType 也是強型別轉換函數,網路上有建議轉換 xxx 為強型別

    xxx = CType(xxx, MyType)

    不過我自己用的有問題,所以我通常針對引數做手動強型別轉換

    xxx.Method(CShort(1234), CInt(2345))

    注意,用強型別轉換函數將無法使用 ByRef 。例如:變數 a 在記憶體位置 x ,用強型別轉換函數轉換後,會得到暫存變數 b 在記憶體位置 y ,引數是傳 y 位置過去,並非是 x 位置,所以變數 a 並不會被置換,而變數 b 卻會被釋放,所以對於 ByRef 會遺失。

    謝謝您仔細的回答

    讓我的觀念又清楚不少

    但是使用的元件就是用ByRef在傳.....>///<

    所以還是會有問題

    不過真的很謝謝您的回答~~~

    2006年10月18日 下午 04:12