Динамическое построение структур в памяти

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 11:29

Jack Ferre, благодарствую за предоставленный пример. ) К сожалению вчера не смог потестировать, так как нахожусь на даче. На дачном компе VB6 нет. Сейчас ставлюсь. Пока визуально изучаю код. Возникли несколько вопросов:

1) Почему потребовалось создавать несколько классов вместо одного ?

2) Почему переменные нельзя передать просто через ParamArray и обработать в методе ?

3) Почему было решено оставить только STDCALL и CDECL в структуре ?

Код: Выделить всё
Public Enum CALLCONV
    CC_CDECL = 1
    CC_STDCALL = 4
End Enum


Причину выпадания сейчас заметил. Последний параметр передавал в функцию DispCallFunc передавал по значению, а не по ссылке.

4) Если не сложно, можете добавить пару комментариев к коду, а то пока не совсем понятно как это всё работает :roll: .

Я пока что свой компонент перепахал так:

Код: Выделить всё
Option Explicit

Private Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" _
    (ByVal lpFileName As String) As Long

Private Declare Function GetProcAddress Lib "kernel32.dll" _
    (ByVal hModule As Long, ByVal lpProcName As String) As Long

Private Declare Function FreeLibrary Lib "kernel32.dll" _
    (ByVal hModule As Long) As Long

Private Declare Function DispCallFunc Lib "OleAut32.dll" _
    (ByVal pvInstance As Long, _
        ByVal oVft As Long, _
        ByVal cc As Long, _
        ByVal vtReturn As Integer, _
        ByVal cActuals As Long, _
        ByVal prgvt As Long, _
        ByVal prgpvarg As Long, _
        ByVal pvargResult As Long) As Long

Enum tagCALLCONV
    CC_FASTCALL = 0
    CC_CDECL = 1
    CC_MSCPASCAL = CC_CDECL + 1
    CC_PASCAL = CC_MSCPASCAL
    CC_MACPASCAL = CC_PASCAL + 1
    CC_STDCALL = CC_MACPASCAL + 1
    CC_FPFASTCALL = CC_STDCALL + 1
    CC_SYSCALL = CC_FPFASTCALL + 1
    CC_MPWCDECL = CC_SYSCALL + 1
    CC_MPWPASCAL = CC_MPWCDECL + 1
    CC_MAX = CC_MPWPASCAL
End Enum

Private Const ERR_SRC = "cLib"

Private lLibraryHandle As Long

Sub Load(FileName As String)
    'Если библиотека уже была загружена, то выгружаем её
    If lLibraryHandle <> 0 Then Unload
    'Получаем хэндл загруженной библиотеки
    lLibraryHandle = LoadLibrary(FileName)
    'Проверяем как прошла загрузка
    If lLibraryHandle = 0 Then Err.Raise vbObjectError + 1, ERR_SRC, "Error loading module"
End Sub

'Метод вызова функций в DLL
Sub CallFunc(ProcName As String, CallConvention As tagCALLCONV, ReturnValueType As VbVarType, ReturnValuePointer As Long, ParamArray Parameters() As Variant)
    Dim lProcAddress As Long
    ReDim aTypes(UBound(Parameters)) As Integer
    ReDim aPointers(UBound(Parameters)) As Long
    Dim i
    'Получаем адрес функции в библиотеке
    lProcAddress = GetProcAddress(lLibraryHandle, ProcName)
   
    If lProcAddress = 0 Then Err.Raise vbObjectError + 1, ERR_SRC, "Function not found"
   
    'Stop
    'Заполняем массив типов переменных
    For i = 0 To UBound(Parameters)
        aTypes(i) = VarType(Parameters(i))
        aPointers(i) = VarPtr(Parameters(i))
    Next
   
    Dim rv As Long
   
    rv = DispCallFunc(0, _
                      lProcAddress, _
                      CallConvention, _
                      ReturnValueType, _
                      UBound(Parameters) + 1, _
                      VarPtr(aTypes(0)), _
                      VarPtr(aPointers(0)), _
                      VarPtr(ReturnValuePointer))
End Sub

'Выгрузка библиотеки
Sub Unload()
    FreeLibrary lhModule
End Sub

'Событие выгрузки экземпляра класса
Private Sub Class_Terminate()
    FreeLibrary lLibraryHandle
End Sub


Хакер,
Хакер писал(а):Обязательно нужно отрывать. Так так и не понял.


Ну зачем же так критично сразу ? ) В обсуждение рождается истина. Возможно предложенный код и не идеален, но если он работает, то это одно из решений. А дальше уже дело за разработчиком. ) Под себя допилить всегда можно. :wink:

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 13:26

Немного допилил. Выкладываю результат.

Сделал Class модуль

Методы:
Load - Загрузка библиотеки
Unload - Выгрузка библиотеки
CallFunc - Вызов необходимой функции

Свойства:
CallingConvention - Read/Write свойство для установки соглашения вызова
ReturnValueType - Read / Write свойство для установки типа возвращаемого значения

Пример работы.
Код: Выделить всё
Sub Main()
    Dim oLib As New cLib
    Dim rv As Long
    oLib.Load "user32.dll"
    rv = oLib.CallFunc("MessageBoxA", 0, StrConv("text", vbFromUnicode), StrConv("caption", vbFromUnicode), 0)
End Sub
Вложения
Test.zip
Пример
(2.49 Кб) Скачиваний: 123

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Динамическое построение структур в памяти

Сообщение The trick » 09.08.2014 (Сб) 13:32

Для чего нужна обертка для DispCallFunc? Максимум нужна отдельная функция, и то не всегда, тем более DispCallFunc не ограничивается одним вызовом функции по адресу (читайте описание).
UA6527P

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 13:39

Кривоус Анатолий, прошу прощения, что ввёл в заблуждение. Из библиотеки PKCS11 я использую штук 10 функций. Эта библиотека стандартизованный "интерфейс" для работы с USB токенами ( USB устройства для хранения ключей и выполнения операций шифрования и подписания. Эдакий инструмент аппаратной защиты ). Так как из всех языков программирования VB я знаю хоть как-то, то взялся за сборку ActiveX компонента, дабы использовать его в системе Клиент-Банк. А обёртку в виде класса пришлось делать, чтобы минимизировать код вызовов функций.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 14:42

Хакер, если не сложно, можешь показать пример как правильно воспользоваться функцией WideCharToMultiByte для подготовки строки в UTF-8 кодировке ?

Сделал поиск по форуму на тему этой функции

Нашёл:
1) http://bbs.vbstreets.ru/viewtopic.php?p=6765824#p6765824
2) http://bbs.vbstreets.ru/viewtopic.php?f=1&t=45362&hilit=Utf8ToUcs2&start=30

К сожалению полной ясности не получил. Правильно ли я понял, что мне нужно конвертировать UCS-2 -> UTF-8 ?

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Динамическое построение структур в памяти

Сообщение The trick » 09.08.2014 (Сб) 14:47

Код: Выделить всё
Option Explicit

Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long
Private Const CP_UTF8 = 65001

Private Sub Form_Load()
    Dim S       As String
    Dim out()   As Byte ' Можно использовать строку, это не важно
    Dim l       As Long
    ' Строка на русском и греческом
    S = "Привет ALX_2002!" & ChrW(&H393) & ChrW(&H3B5) & ChrW(&H3B9) & ChrW(&H3B1) & " ALX_2002!"
    l = WideCharToMultiByte(CP_UTF8, 0, StrPtr(S), Len(S), 0, 0, 0, 0)
    ReDim out(l - 1)
    WideCharToMultiByte CP_UTF8, 0, StrPtr(S), Len(S), out(0), l, 0, 0
    ' Сохраняем в файл
    Open "C:\TestUTF8.txt" For Binary As FreeFile
    Put FreeFile - 1, , out
    Close FreeFile - 1
End Sub
UA6527P

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 14:55

Кривоус Анатолий, премного благодарен Вам за DispCallFunc и за этот пример ! :D Переделываю проект. :lol: Результат превосходит все мои ожидания )

P.S. Я правильно понимаю, что для обратного преобразования нужно использовать уже MultiByteToWideChar ?

Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Re: Динамическое построение структур в памяти

Сообщение Jack Ferre » 09.08.2014 (Сб) 16:15

Переписал. Объединил классы в один. Урезал интерфейс.
DispCallFunc.rar
(16.64 Кб) Скачиваний: 126


Моя идея заключается в том, чтобы использовать DispCallFunc только в процессе разработки программы, а в релизе - функции API объявленные как CDecl. Для этого экранировать использование DispCallFunc флагом условной компиляции RELEASE.

Объявление:
Код: Выделить всё
#If RELEASE Then
    ' Объявляем функции для релиза проекта
    Private Declare Function MessageBoxA Lib "user32" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
#Else
    ' Объявляем библиотеки (по одному объекту на каждую библиотеку)
    Private libUser32 As New CDispCall
#End If


Функции-посредники:
Все эти функции должны быть экранированы с помощью
#If RELEASE = 0 Then
...
#End If

Код функции-посредника на примере MessageBoxA
Код: Выделить всё
Private Function MessageBoxA(ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
    ' Переменная, хранящая указатель на функцию.
    Static lpFunc As Long
   
    ' Загружаем библиотеку. Выполняется только 1 раз.
    ' Получаем указатель. Выполняется только 1 раз.
    If lpFunc = 0 Then lpFunc = libUser32.GetProcAddr("user32", "MessageBoxA")
   
    ' Продолжаем только если получили указатель.
    If lpFunc Then
        ' Указываем количество аргументов.
        libUser32.Count = 4
       
        ' Кладем аргементы в массив.
        libUser32.Push hwnd
        libUser32.Push StrConv(lpText, vbFromUnicode)
        libUser32.Push StrConv(lpCaption, vbFromUnicode)
        libUser32.Push wType
       
        ' Указываем CALLCONV,
        ' Указываем возвращаемый тип,
        ' Вызываем функцию,
        ' Присваиваем результат функцие-посреднику,
        MessageBoxA = CLng(libUser32.CallFunc(lpFunc, CC_STDCALL, vbLong))
    End If
End Function

Думаю написать с десяток таких функций методом "копировать-вставить" не составит труда.

Использование:
Ни чем не отличается между версиями RELEASE и DEBUG.
Код: Выделить всё
MessageBoxA(hwnd, "Hello!", "CDispCall sample", vbYesNo)



P.S. Убрал swprintf из примера. Объявить swprintf c помощью Declare не получилось. Получилось её вызвать только как Stdcall с несколькими параметрами as Long вместо ParamArray() as Variant. Все остальные попытки увенчались ошибкой "bad call convention". Нашел sprintf в топике хакера про CDelc в VB. Подскажите какую-нибудь другую функцию cdecl из стандартных библиотек на которой можно потренироваться.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 17:13

Никак не могу найти где косячу. Внутри функции Ucs2ToUtf8 получаю ret = 0 после вызова WideCharToMultiByte. Ткните носом пожалуйста что не так делаю ? :oops:

Код: Выделить всё
Option Explicit

Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, _
                                                                ByVal dwFlags As Long, _
                                                                lpMultiByteStr As Any, _
                                                                ByVal cchMultiByte As Long, _
                                                                lpWideCharStr As Any, _
                                                                ByVal cchWideChar As Long) As Long

Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, _
                                                                ByVal dwFlags As Long, _
                                                                lpWideCharStr As Any, _
                                                                ByVal cchWideChar As Long, _
                                                                lpMultiByteStr As Any, _
                                                                ByVal cchMultiByte As Long, _
                                                                ByVal lpDefaultChar As Long, _
                                                                ByVal lpUsedDefaultChar As Long) As Long


Private Const CP_UTF8 = 65001

Sub Main()
    Dim sTmpString As String
    Dim bByteArray() As Byte
    sTmpString = "Тест"
    bByteArray = Ucs2ToUtf8(sTmpString)
    sTmpString = Utf8ToUcs2(bByteArray)
End Sub

Function Ucs2ToUtf8(ByRef sInputUcs2Str As String) As Byte()
    Dim ret As Long
    Dim nInpLength As Long: nInpLength = LenB(sInputUcs2Str) - 1
    If nInpLength = 0 Then Exit Function
    ReDim bUcs2ToUtf8(nInpLength) As Byte
    ret = WideCharToMultiByte(CP_UTF8, 0, _
                              ByVal StrPtr(sInputUcs2Str), nInpLength, _
                              bUcs2ToUtf8(LBound(bUcs2ToUtf8)), nInpLength, 0, 0)
   
    If ret = 0 Then
        Error 51
    Else
        ReDim Preserve bUcs2ToUtf8(ret - 1)
        Ucs2ToUtf8 = bUcs2ToUtf8
    End If
End Function

Public Function Utf8ToUcs2(ByRef sInputUtf8Str() As Byte) As String
    Dim ret As Long
    Dim nInpLength As Long: nInpLength = ByteArraySize(sInputUtf8Str)
    If nInpLength = 0 Then Exit Function Else Utf8ToUcs2 = Space(nInpLength)
    ret = MultiByteToWideChar(CP_UTF8, 0, _
                              sInputUtf8Str(LBound(sInputUtf8Str)), nInpLength, _
                              ByVal StrPtr(Utf8ToUcs2), nInpLength)
    If ret = 0 Then Error 51 Else Utf8ToUcs2 = Left$(Utf8ToUcs2, ret)
End Function

Private Function ByteArraySize(ByRef b() As Byte) As Long
    On Error Resume Next
    ByteArraySize = UBound(b) - LBound(b) + 1
End Function
Последний раз редактировалось ALX_2002 09.08.2014 (Сб) 17:40, всего редактировалось 2 раз(а).

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Динамическое построение структур в памяти

Сообщение Хакер » 09.08.2014 (Сб) 17:21

4-ый аргумент должен быть в символах, а не в байтах.

Вот она хвалёная «мягкость» типов. Если бы для кол-ва символов и кол-ва байтов приходилось бы применять разные несовместимые между собой типы, то ошибки бы не возникло.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Динамическое построение структур в памяти

Сообщение Хакер » 09.08.2014 (Сб) 17:27

Кстати, этот код неправильный. Буфера запросто может не хватить. С чего ты взял, что длина UTF-8 строки в байтах окажется гарантированно не больше, чем длина исходной строки в символах, помноженная на 2?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 17:31

Как раз думал об этом. Т.е нужно делать как в примере, который привёл Анатолий Кривоус ? ) Сначала оценивать размер этой функцией и создавать массив нужной длины ? Или можно выделить массив с запасом, а потом урезать его на нужную длину ?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Динамическое построение структур в памяти

Сообщение Хакер » 09.08.2014 (Сб) 17:39

Я в последний раз, когда мне это нужно было делать на VB6, использовал сдедующий код:
Код: Выделить всё
Private Function OlestrEstimateUtf8Len(ByRef olestrval As String, ByVal nByteLim As Long) As Long
   
    Dim i           As Long
    Dim nChars      As Long
    Dim nBytes      As Long
    Dim pStr        As Long
    Dim wSym        As Long
    Dim nSymBytes   As Long
   
    pStr = StrPtr(olestrval)
    nChars = Len(olestrval)
    For i = 0 To nChars - 1
        GetMem2A ByVal pStr + 2 * i, wSym
        Select Case wSym
            Case Is < &H80&:  nSymBytes = 1
            Case Is < &H800&: nSymBytes = 2
            Case Else:        nSymBytes = 3
        End Select
       
        If nBytes + nSymBytes > nByteLim Then
            olestrval = Left$(olestrval, i)
            Exit For
        Else
            nBytes = nBytes + nSymBytes
        End If
    Next i
   
    OlestrEstimateUtf8Len = nBytes
End Function

Он не только прикидывает заранее, сколько в точности займёт UTF8-представление UCS2-строки, но и аккуратно подрезает исходную строку по границе крайнего символа, если всё, что идёт после этого символа своим представлением выходит за границу разрешённого лимита на размер выходного буфера. Иными словами, исходная строка не будет обрезана где-то в середине символа.

Не знаю, нужно ли тебе это, но неплохо бы свериться с документацией на PKCS11 и посмотреть, какой там декларируется лимит на длину передаваемых строк в байтах.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 17:44

Японский бог :shock:. Так раз функция сама возвращает размер то зачем самим его считать ? Дело в идеологической неправильности такого подхода или функция может "ошибиться" ?

Задумался. Если я делаю массив в 2 раза больше, то его точно хватит для размещения данных ? Больше двух байт на символ же не может быть выделено ?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Динамическое построение структур в памяти

Сообщение Хакер » 09.08.2014 (Сб) 17:52

ALX_2002 писал(а):Больше двух байт на символ же не может быть выделено ?

Повторяю:
Хакер писал(а):С чего ты взял, что длина UTF-8 строки в байтах окажется гарантированно не больше, чем длина исходной строки в символах, помноженная на 2?


Вообще, это свидетельствует об обмане, который вскрылся. Я тебе написал:
Хакер писал(а):Не смей писать ни строчки кода, пока не прочитаешь абсолютный минимум, который каждый разработчик должен знать о юникоде и кодировках.


Ты же, тем временем, взялся писать код, хотя чтение бросил. Можно однозначно говорить, что ты её не прочитал, потому что там ясно указано, что в UTF-8 одному символу может соответствовать от одного до шести байтов.

Не люблю обман.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 09.08.2014 (Сб) 18:00

Хакер,
Поэтому была изобретена блестящая концепция UTF-8. UTF-8 был другой системой хранения вашей последовательности кодовых точек Unicode, тех самых волшебных U+ чисел, используя те же 8 битов в памяти. В UTF-8 каждая кодовая точка с номерами от 0 до 127 сохранялись в единственном байте. Как только номер кодовой точки станет равна 128 и выше, для хранения используется 2, 3, и, фактически, до 6 байтов.


Действительно упустил этот момент. :( Виновен. Каюсь.

Пока что оставил так.
Код: Выделить всё
Function Ucs2ToUtf8(ByRef sInputUcs2Str As String) As Byte()
    Dim ret As Long
    Dim nInpLength As Long: nInpLength = Len(sInputUcs2Str)
    If nInpLength = 0 Then Exit Function
    ret = WideCharToMultiByte(CP_UTF8, 0, _
                              ByVal StrPtr(sInputUcs2Str), nInpLength, _
                              0, 0, 0, 0)
   
    If ret = 0 Then Error 51
    ReDim bUcs2ToUtf8(0 To ret - 1) As Byte
    ret = WideCharToMultiByte(CP_UTF8, 0, _
                              ByVal StrPtr(sInputUcs2Str), nInpLength, _
                              bUcs2ToUtf8(LBound(bUcs2ToUtf8)), ret, 0, 0)
   
    If ret = 0 Then Error 51
    Ucs2ToUtf8 = bUcs2ToUtf8
End Function

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Динамическое построение структур в памяти

Сообщение Хакер » 09.08.2014 (Сб) 19:01

1. WET-код (должен быть DRY)
2. Зачем два массива и лишнее копирование массивов?
3. С пустыми строками случится фейл (снаружи).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 10.08.2014 (Вс) 9:28

Хакер писал(а):1. WET-код (должен быть DRY)

Не могу не согласиться. )
Хакер писал(а):2. Зачем два массива и лишнее копирование массивов?

Опять же согласен. Пытался использовать родной от самой функции - т.е сделать
Код: Выделить всё
ReDim Ucs2ToUtf8(0 To ret - 1) As Byte


Но тогда Ucs2ToUtf8(0) и Ucs2ToUtf8(Lbound(Ucs2ToUtf8)) вызывает ошибку, так как рассматривается как повторное обращение к функции, а не к элементу массива. Подскажи пожалуйста - как правильно это делать ?

Хакер писал(а):3. С пустыми строками случится фейл (снаружи).

Из-за того что вернётся пустой Byte() ? Хм. Т.е ситуация If nInpLength = 0 Then Exit Function. А как быть ?

P.S Хм. Сейчас проверил с пустой строкой. Код отработал нормально. Просто выдал пустой MsgBox.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Динамическое построение структур в памяти

Сообщение The trick » 10.08.2014 (Вс) 10:21

ALX_2002 писал(а):Подскажи пожалуйста - как правильно это делать ?

Тебе же написали - правильней создать отдельный тип UTF8_STRING, пусть функция возвращает его.
UA6527P

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Динамическое построение структур в памяти

Сообщение ALX_2002 » 10.08.2014 (Вс) 11:08

Кривоус Анатолий, ааа. Вроде дошло. ) Спасибо ! :D

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: SemrushBot и гости: 46

    TopList