将 VB6 自定义类型(具有固定长度字符串)转换为 VB .NET
我已经使用 UpgradeWizard 将一些 VB6 代码(在自定义类型中使用固定长度字符串)升级到 VB .NET,但在使用 LSet 方法时遇到了问题,我希望有人可以帮助我解决这个问题。
现有的 VB6 代码(类型声明);
Public Type MyType
PROP1 As String * 15
PROP2 As String * 25
End Type
Public Type MyTypeBuffer
Buffer As String * 40
End Type
用法示例;
LSet instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer
将其升级到 .NET 的合适方法是什么?
使用升级向导,我得到以下信息;
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
_
Public Structure MyType
<VBFixedString(15),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=15)> _
Dim PROP1 As FixedLengthString
<VBFixedString(25),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=25)> _
Dim PROP2 As FixedLengthString
Public Shared Function CreateInstance() As MyType
Dim result As New MyType
result.PROP1 = New FixedLengthString(15)
result.PROP2 = New FixedLengthString(25)
Return result
End Function
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
_
Public Structure MyTypeBuffer
<VBFixedString(CLVHDR_REC_LENGTH),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=40)> _
Dim Buffer As FixedLengthString
Public Shared Function CreateInstance() As MyTypeBuffer
Dim result As New MyTypeBuffer
result.Buffer = New FixedLengthString(40)
Return result
End Function
End Structure
FixLengthString 来自命名空间 Microsoft.VisualBasic.Compatibility.VB6。
升级向导失败的地方在于 LSet。它产生了以下内容;
instOfMyTypeBuffer.Buffer = LSet(...)
instOfMyType = LSet(instOfMyTypeBuffer)
编译失败,出现这些错误;
“字符串”类型的值不能是 转换为 'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'
未为参数指定参数 “公共职能”的“长度” LSet(源为字符串,长度为 整数)作为字符串'
“MyTypeBuffer”类型的值不能是 转换为“字符串”
因此,我可以使用 ToString() 来获取其中的一部分,但仍然存在 LSet 方法调用本身的问题。我应该怎么做才能重新创建原始功能?升级向导是否给了我一个完全不合适的转换,或者它是否可以挽救为可用的东西?
I have upgraded some VB6 code, which uses fixed length strings in custom types, to VB .NET by using the UpgradeWizard and am having trouble with the use of the LSet method that I was hoping someone could help me out with.
The Existing VB6 code (type declarations);
Public Type MyType
PROP1 As String * 15
PROP2 As String * 25
End Type
Public Type MyTypeBuffer
Buffer As String * 40
End Type
Example usage;
LSet instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer
What would be an appropriate way to upgrade this to .NET?
Using the UpgradeWizard, I get the following;
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
_
Public Structure MyType
<VBFixedString(15),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=15)> _
Dim PROP1 As FixedLengthString
<VBFixedString(25),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=25)> _
Dim PROP2 As FixedLengthString
Public Shared Function CreateInstance() As MyType
Dim result As New MyType
result.PROP1 = New FixedLengthString(15)
result.PROP2 = New FixedLengthString(25)
Return result
End Function
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
_
Public Structure MyTypeBuffer
<VBFixedString(CLVHDR_REC_LENGTH),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=40)> _
Dim Buffer As FixedLengthString
Public Shared Function CreateInstance() As MyTypeBuffer
Dim result As New MyTypeBuffer
result.Buffer = New FixedLengthString(40)
Return result
End Function
End Structure
FixedLengthString is coming from the namespace Microsoft.VisualBasic.Compatibility.VB6.
Where the Upgrade Wizard fails is when it comes to LSet. It produced the following;
instOfMyTypeBuffer.Buffer = LSet(...)
instOfMyType = LSet(instOfMyTypeBuffer)
Which fails to compile, giving these errors;
Value of type 'String' cannot be
converted to
'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'Argument not specified for parameter
'Length' of 'Public Function
LSet(Source As String, Length As
Integer) As String'Value of type 'MyTypeBuffer' cannot be
converted to 'String'
So, I can use ToString() to get part of the way there, but there is still the issue of the LSet method call itself. What should I do to recreate the original functionality? Has the Upgrade Wizard given me a totally inappropriate conversion, or is it salvageable into something usable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
LSet 是 VB6 中一个相当古怪的语句:请参阅 说明在手册中。
它在您的代码中以一种特别古怪的方式使用。
LSet instOfMyTypeBuffer.Buffer = ...
这在 VB6 和迁移的 Vb.Net 中都是多余的。当您为固定长度字符串分配新值时,它总是会用空格填充!
所以只需更改为这个(在 VB6 或 VB.Net 中)
instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer
更有趣。这会将内存从一种类型的实例复制到另一种类型的实例中,而不进行检查。 咕噜咕噜!
查看类型的定义,我认为这只是将
instOfMyBuffer
中的前 15 个字符放入instOfMyType.PROP1
中,并将其余 25 个字符放入instOfMyType.PROP2< /代码>。
我偶尔会看到这被用作处理从文件读取的固定长度字符串记录的一种丑陋的方式。例如,前 15 个字符可能是一个人的名字,接下来的 25 个字符可能是姓氏。
您可以用此代码替换(在 VB6 或 VB.Net 中)。
instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)
Hans 建议放弃固定长度字符串。如果这很容易 - 并且取决于代码库的其余部分,它可能很容易,或者可能很难 - 这是一个很好的建议。
LSet is a rather quirky statement in VB6: see description in the manual.
It's being used in a particularly quirky way in the code you have.
LSet instOfMyTypeBuffer.Buffer = ...
This is redundant both in the VB6 and the migrated Vb.Net. When you assign a new value to a fixed-length string, it always pads out with spaces anyway!
So just change to this (in either VB6 or VB.Net)
instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer
More interesting. This copies the memory from an instance of one type into an instance of another type, with no checks. Gulp!
Looking at the definitions of the types, I think this simply puts the first 15 characters from
instOfMyBuffer
intoinstOfMyType.PROP1
and the remaining 25 characters intoinstOfMyType.PROP2
.I have occasionally seen this used as an ugly way of processing fixed-length string records read from a file. For example the first fifteen characters might be a person's first name, and the next 25 the last name.
You could just replace with this code (in either VB6 or VB.Net).
instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)
Hans suggested ditching the fixed-length strings. If that's easy - and it depends on the rest of your code base, it might be easy, or it might be hard - it's good advice.