none
请教关于Structure作为参数传递的问题 RRS feed

  • 问题

  • 我定义了一个结构体DisplayProps,然后定义了Public Shared Sub LSet(ByRef dst As ValueType, ByVal src As ValueType)来实现两个结构体的拷贝。

    运行以下代码会报Cast异常,该怎么修改?

    写法一:

    Dim udtData As DisplayProps

    LSet(udtData, srcData)      〈-----运行完这句话就报Cast异常

     

    写法二:

    Dim udtData As DisplayProps

    Dim val as ValueType

    val = udtData

    LSet(val, srcData)     

    udtData = val                        〈-----运行完这句话就报Cast异常

     

    我把代码贴上来了:

     

    <Serializable()> Public Structure DisplayProps
      Dim BsStateCd As Integer
      Dim BsActGsCt As Integer
      <VBFixedString(10),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,SizeConst:=10)> Public BsMaxFs() As Char
     End Structure

    <Serializable()> Public Structure DisplayData
      <VBFixedString(154),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,SizeConst:=154)> Public BufferData() As Char
     End Structure

     

        Public Shared Sub LSet(ByRef dst As ValueType, ByVal src As ValueType)
            Try
                Dim BF As New Binary.BinaryFormatter()
                Dim MS As MemoryStream
                Dim byt() As Byte
                Dim strBytes As String
                Dim strSrc As String
                Dim strDst As String
                Dim strSrcData As String
                Dim strDstData As String
                Dim strSrcType() As String
                Dim strDstType() As String
                Dim vt As ValueType
                Dim fi As Reflection.FieldInfo

                strSrc = src.GetType().ToString()
                strSrcType = strSrc.Split("+")

                strDst = dst.GetType().ToString()
                strDstType = strDst.Split("+")

                strDstData = strDstType(strDstType.Length - 1).Substring(strDstType(strDstType.Length - 1).Length - 5, 5).ToLower()
                strSrcData = strSrcType(strSrcType.Length - 1).Substring(strSrcType(strSrcType.Length - 1).Length - 5, 5).ToLower()

                If (strDstData.CompareTo(strSrcData) = 0) Then 'data->data or 'props->props
                    MS = New MemoryStream()
                    BF.Serialize(MS, src)
                    byt = MS.ToArray()
                    MS.Position = 0
                    dst = BF.Deserialize(MS)
                Else
                    If (strSrcData.CompareTo("props") <> 0) Then 'data->props
                        Dim retStr As String
                        vt = src
                        fi = src.GetType().GetField("BufferData")
                        retStr = fi.GetValue(vt)

                        byt = System.Text.Encoding.Unicode.GetBytes(retStr)
                        MS = New MemoryStream(byt)
                        MS.Position = 0
                        dst = BF.Deserialize(MS)
                    Else 'props->data
                        MS = New MemoryStream()
                        BF.Serialize(MS, src)
                        byt = MS.ToArray()
                        strBytes = System.Text.Encoding.Unicode.GetString(byt)

                        vt = dst
                        fi = dst.GetType().GetField("BufferData")
                        fi.SetValue(vt, strBytes.ToCharArray())
                    End If
                End If

            Catch ex As Exception
                Throw ex
            End Try
        End Sub

     

      Public Sub SetState(ByVal Buffer As String)
            Dim udtData As DisplayData

            Dim udtProps As DisplayProps
            Dim val3 As ValueType
            Try
                udtData.BufferData = Buffer   'Buffer是DisplayProps序列化后的字符串
                val3 = udtProps
                LSet(val3, udtData)

      udtProps = val3                '这里报错
            Catch ex As Exception
                MessageBox.Show(ex.StackTrace)
            End Try

        End Sub

    2008年11月17日 23:22

答案

  • 可能是你传进来的Buffer有问题,我试了一下,没问题

     

    Code Snippet

    Public Sub SetState(ByVal Buffer As String)

            Dim BF As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            Dim MS As MemoryStream
            Dim byt() As Byte
            Dim strBytes As String
            Dim strSrc As String
            Dim strDst As String
            Dim strSrcData As String
            Dim strDstData As String
            Dim strSrcType() As String
            Dim strDstType() As String
            Dim vt As ValueType
            Dim fi As Reflection.FieldInfo

            Dim udtData As DisplayData

            Dim udtProps As DisplayProps
            Dim val3 As ValueType
            Try
                Dim testProps As DisplayProps
                testProps.BsMaxFs = "X"
                MS = New MemoryStream()
                BF.Serialize(MS, testProps)
                byt = MS.ToArray()
                strBytes = System.Text.Encoding.Unicode.GetString(byt)

                udtData.BufferData = strBytes   'Buffer是DisplayProps序列化后的字符串

                val3 = udtProps
                LSet(val3, udtData)


                udtProps = val3                '这里报错
            Catch ex As Exception
                MessageBox.Show(ex.StackTrace)
            End Try

        End Sub

     

     

     

    2008年11月18日 4:25
    版主
  • 运算符重载,

    重写运算符=号,在当前域中。



    那么 凡是    结构体 负值 都会调用这个 重载,设计时,需要 首先 辨别  用户要负值的 结构体,是不是你 处理的结构体的同一个类型

    这是比较方便的方法!

    参看如下地址
    2008年11月18日 5:29

全部回复

  • srcData是什么?

    2008年11月18日 1:05
    版主
  • 我把代码贴上来了,请参看上面的帖子。谢谢!

    2008年11月18日 2:28
  • 可能是你传进来的Buffer有问题,我试了一下,没问题

     

    Code Snippet

    Public Sub SetState(ByVal Buffer As String)

            Dim BF As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            Dim MS As MemoryStream
            Dim byt() As Byte
            Dim strBytes As String
            Dim strSrc As String
            Dim strDst As String
            Dim strSrcData As String
            Dim strDstData As String
            Dim strSrcType() As String
            Dim strDstType() As String
            Dim vt As ValueType
            Dim fi As Reflection.FieldInfo

            Dim udtData As DisplayData

            Dim udtProps As DisplayProps
            Dim val3 As ValueType
            Try
                Dim testProps As DisplayProps
                testProps.BsMaxFs = "X"
                MS = New MemoryStream()
                BF.Serialize(MS, testProps)
                byt = MS.ToArray()
                strBytes = System.Text.Encoding.Unicode.GetString(byt)

                udtData.BufferData = strBytes   'Buffer是DisplayProps序列化后的字符串

                val3 = udtProps
                LSet(val3, udtData)


                udtProps = val3                '这里报错
            Catch ex As Exception
                MessageBox.Show(ex.StackTrace)
            End Try

        End Sub

     

     

     

    2008年11月18日 4:25
    版主
  • 想请教一下,要实现两个结构体的拷贝,除了序列化,还有没有其他更好的方法?

    2008年11月18日 4:44
  • 直接赋值

    .

    Code Snippet

    A.A1=B.B1

     

     

    2008年11月18日 4:54
    版主
  • 因为我事先是不知道每个结构体的成员的,想做一个共通的。

    2008年11月18日 4:56
  • 运算符重载,

    重写运算符=号,在当前域中。



    那么 凡是    结构体 负值 都会调用这个 重载,设计时,需要 首先 辨别  用户要负值的 结构体,是不是你 处理的结构体的同一个类型

    这是比较方便的方法!

    参看如下地址
    2008年11月18日 5:29
  • 谢谢回复!我试试。主要是为了代替VB6.0中的LSet用的。

    2008年11月18日 7:34