Поделиться через


Рекомендации по обновлению. Настройка типов данных для интерфейсов Win32 API

Обновлен: Ноябрь 2007

Многие интерфейсы API могут использоваться так же, как и в Visual Basic 6.0, однако следует помнить о необходимости согласования соответствующих типов данных. Тип данных Long в Visual Basic 6.0 является типом данных Integer в Visual Basic 2008, а тип данных Integer в Visual Basic 6.0 является типом данных Short в Visual Basic 2008. Эти изменения вносятся при обновлении, и простые интерфейсы API работают так же, как в Visual Basic 6.0. Пример

Private Declare Function GetVersion Lib "kernel32" () As Long
Function GetVer()
    Dim Ver As Long
    Ver = GetVersion()
    MsgBox ("System Version is " & Ver)
End Function

заменяется на:

Private Declare Function GetVersion Lib "kernel32" () As Integer
Function GetVer()
    Dim Ver As Integer
    Ver = GetVersion()
    MsgBox("System Version is " & Ver)
End Function

Кроме обновляемых числовых типов данных, в Visual Basic 6.0 существует тип данных строк фиксированной длины, которые не поддерживаются в Visual Basic 2008; после обновления они преобразуются в оболочку класса строк фиксированной длины. Во многих случаях в Visual Basic 6.0 одни и те же действия можно выполнить, используя обычные строки. Пример

Private Declare Function GetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Long) As Long
Function GetUser()
    Dim Ret As Long
    Dim UserName As String
    Dim Buffer As String * 25
    Ret = GetUserName(Buffer, 25)
    UserName = Left$(Buffer, InStr(Buffer, Chr(0)) - 1)
    MsgBox (UserName)
End Function

можно улучшить, используя обычную строку с явно заданной длиной "25" вместо строки фиксированной длины:

Dim Buffer As String
Buffer = String$(25, " ")

Обновление до Visual Basic 2008 происходит следующим образом:

Declare Function GetUserName Lib "advapi32.dll" Alias _ 
"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Function GetUser()
    Dim Ret As Integer
    Dim UserName As String
    Dim Buffer As String
    Buffer = New String(CChar(" "), 25)
    Ret = GetUserName(Buffer, 25)
    UserName = Left(Buffer, InStr(Buffer, Chr(0)) - 1)
    MsgBox(UserName)
End Function

В некоторых случаях лучше всего в Visual Basic 2008 выполняется обработка строк, передаваемых интерфейсам API, поскольку можно при желании задать способ передачи строки с помощью зарезервированных слов ANSI и UNICODE.

Существует три случая, в которых необходимо вносить изменения. Первый происходит при передаче типов, определенных пользователем, которые содержат строки фиксированной длины, или при передаче массивов байтов интерфейсам API. В Visual Basic 2008 может потребоваться изменение кода путем добавления атрибута MarshallAs (из класса System.Runtime.InteropServices) в каждую строку фиксированной длины или в массив байтов в определяемом пользователем типе. Вторым случаем является использование переменой типа As Any в операторе Declare. Эта возможность не поддерживается в Visual Basic 2008. Переменные типа As Any часто использовались для передачи переменной, которая являлась строкой или Null. В Visual Basic 6.0 эти переменные можно заменить на два API — один со строками, второй с длиной. Например, API GetPrivateProfileString имеет параметр lpKeyName типа As Any:

Private Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString _
As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

“As Any” можно удалить, заменив Declare двумя способами: в одном случае будет приниматься значение типа Long, в другом — строковое значение:

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString _
As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer

Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32" _
Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Integer, ByVal lpDefault As String, ByVal _
lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName _
As String) As Integer

Если интерфейсу API необходимо передать пустое значение, можно воспользоваться версией GetPrivateProfileStringNullKey. Это означает обновление функции до версии Visual Basic 2008.

Третий случай — использование API, создающих потоки, наследование от классов Windows, выполнение привязки к очереди сообщений и т. д. Некоторые из этих функций могут вызывать ошибку во время выполнения в Visual Basic 2008. Многие из этих API имеют эквиваленты в Visual Basic 2008 или в среде .NET Framework. Каждый конкретный случай должен рассматриваться отдельно.

См. также

Другие ресурсы

Рекомендации по обновлению, касающиеся языка