如何从VB.net中的VB6重写“LSet”(带结构类型)?

时间:2011-12-30 07:07:24

标签: vb.net vb6 vb6-migration

我有一个VB6应用程序,它使用LSet()和两个用户定义的数据类型(Type),将数据从一种类型分配给另一种类型,例如:

Lset type1 = Type2

现在我必须在VB.net中应用等效逻辑。但是,在VB.net中,LSet cannot be used against different types(VB6中的类型)。

如何在VB.net中实现VB6 LSet逻辑?

示例/典型代码:

Public MQ_Policy As typPolicyDataRetrieval 
Public typPolicyDataBlock As gtypPolicyDataBlock 

With MQ_Policy.Input 
   .PcPolicyIDNum = Mid(InputString, 1, 8) 
   .PcPolicyIDNumPrefix = " " 
   .Datalength = Format$(CLng(Len(MQ_Policy)) - (Len(MQ_Policy.MQHeader) + Len(MQ_Policy.Input.Datalength)), String$(Len(.Datalength), "0")) 
End With 

LSet typPolicyDataBlock = MQ_Policy

感谢您的所有帮助。

2 个答案:

答案 0 :(得分:1)

在此处查看更好的答案:Converting VB6 Custom Type (with Fixed Length Strings) to VB .NET

简而言之,LSet与类型一起使用时,会将内存从一个地方复制到另一个地方!所以它不应该在任何情况下使用。原始代码并不好,所以将其“原样”转换为一个坏主意。

如果对象兼容,你应该能够用Cast替换它,或者写一个转换器函数来手动更改类型。

答案 1 :(得分:1)

你不应该在VB.NET中这样做 还有其他方法,例如将转换运算符从一种类型定义到另一种类型,然后在代码中使用它们:

Private Structure t1
    Public a As Short
    Public b As Short
End Structure

Private Structure t2
    Public v As Integer

    Public Shared Widening Operator CType(ByVal v As t1) As t2
        Return New t2 With {.v = v.a Or (CType(v.b, Integer) << 16)}
    End Operator
End Structure

Sub Main()
    Dim v1 As t1, v2 As t2

    v2 = v1 ' Works!
End Sub

但是,如果您确定应该执行逐字节复制,并且您知道alignment issues并且对它们感到满意,那么您可以这样做:

Imports System.Runtime.InteropServices

Public Function CopyStructure(ByVal s As Object, ByVal ResultType As System.Type) As Object
    Dim h As GCHandle

    Try
        h = GCHandle.Alloc(s, GCHandleType.Pinned)

        Return Marshal.PtrToStructure(h.AddrOfPinnedObject, ResultType)
    Finally
        If h.IsAllocated Then h.Free()
    End Try
End Function

Sub Main()
    Dim v1 As t1, v2 As t2

    v2 = DirectCast(CopyStructure(v1, GetType(t2)), t2)
End Sub