问题描述
我已经使用 UpgradeWizard 将一些在自定义类型中使用固定长度字符串的 VB6 代码升级到 VB .NET,并且在使用 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.
现有的 VB6 代码(类型声明);
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
用法示例;
LSet instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer
将其升级到 .NET 的合适方法是什么?
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 来自命名空间 Microsoft.VisualBasic.Compatibility.VB6.
FixedLengthString is coming from the namespace Microsoft.VisualBasic.Compatibility.VB6.
升级向导失败的地方在于 LSet.它产生了以下内容;
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;
字符串"类型的值不能转换成'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'
没有为参数指定参数公共职能"的长度"LSet(源为字符串,长度为整数)作为字符串'
Argument not specified for parameter 'Length' of 'Public Function LSet(Source As String, Length As Integer) As String'
MyTypeBuffer"类型的值不能转换为字符串"
Value of type 'MyTypeBuffer' cannot be converted to 'String'
所以,我可以使用 ToString() 来获得其中的一部分,但仍然存在 LSet 方法调用本身的问题.我应该怎么做才能重新创建原始功能?升级向导是否给了我一个完全不合适的转换,或者它是否可以挽救成可用的东西?
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?
推荐答案
LSet 是 VB6 中一个相当古怪的语句:参见 说明书中的说明.
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 = ...
这在 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)
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 frominstOfMyBuffer
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 建议放弃固定长度的字符串.如果这很容易 - 并且取决于您的代码库的其余部分,它可能很容易,或者它可能很难 - 这是个好建议.
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.
这篇关于将 VB6 自定义类型(具有固定长度字符串)转换为 VB .NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!