powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Совмщение переменных разного типа
25 сообщений из 40, страница 1 из 2
Совмщение переменных разного типа
    #40014607
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бинарный файл board.tjb содержит данные (блоки) разного типа (int long sring …)
Всё содержимое бинарного файла я считываю в массив типа Byte
Для поиска строк в блоке текста я использую ф-ю InStr, но для этого приходится сначала «перегнать» блок в строковую переменную.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Dim i As Integer, l As Long, str As String * 100

l = FileLen(«board.tjb»)
ReDim b(l) As Byte

get #1,,b

str = ""
For i = 100 To 200
    str = str & Chr(b(i))
Next i
i= InStr(str, "Component")


А нельзя ли как-то совместить некую строковую переменную с элементами с 100 по 200 массива b , чтобы избежать копирования блока в переменную (некий аналог ссылок из С++) ?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40014632
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.,

Можно не перегонять байтовый массив в строку, а сразу искать нужный паттерн в массиве.

авторFor i = 100 To 200
str = str & Chr(b(i))
Next i

Очень медленный вариант. Копирование по-одному байту в цикле. Лучше скопировать сразу весь блок в 100 байтов в строку с помощью API функции CopyMemory.

авторА нельзя ли как-то совместить некую строковую переменную с элементами с 100 по 200 массива b , чтобы избежать копирования блока в переменную (некий аналог ссылок из С++) ?


Если бы VB6 поддерживал Union как Си или PowerBasic можно было бы легко совместить. А так имхо простого варианта нет.
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40014651
ATM-TURBO 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дмитрий П.,

используй функцию StrStrA
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40014671
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.,

во первых, вы можете читать не в байтовый массив, а сразу в строку.

Если какой-то другой, не показанной логикой определяется необходимость работы именно с байтовым массивом,
то поразглядывайте вот такой вариант кода:
(он не для всякого содержания произвольного файла правильно отработает,
могут быть кости в много слов, но все равно поглядите.)
Вариант, кстати, не единственный, но смысла пускаться в другие особого нет, для некоторого подмножества содержимого файла.
В частности - здесь точно подразумевается, что в файле сидят строки в ANSI - кодировке.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
Sub test()
  Rem предполагается дефолтный option base 0
  Dim ba_search() As Byte
  Dim ba_pattern() As Byte
  
  Rem эта строка имитирует получение бинарных данных из файла
  ba_search = StrConv("В этой строке есть первый Component, и есть второй Component.", vbFromUnicode)
  
  Rem это образец поиска, приведенный к "бинарному виду", каким его ждать из файла
  ba_pattern = StrConv("Component", vbFromUnicode)
  Dim i As Long, jstart As Long, k As Long
  jstart = 1 ' в строковые функции надо отдавать jstart > 0
  
  i = InStrB(jstart, ba_search, ba_pattern, vbBinaryCompare)
  Debug.Print "нашли первый Component в позиции массива "; i - 1 ' минус один или нет - зависит от option base
  Debug.Print "извлечен_1 функцией: "; StrConv(MidB(ba_search, i, UBound(ba_pattern) + 1), vbUnicode) ' здесь аналогично про +1
  Debug.Print "...массивом: ";
  
  For k = i - 1 To i - 1 + UBound(ba_pattern)
    Debug.Print Chr$(ba_search(k));
  Next
  Debug.Print
  
  jstart = i + UBound(ba_pattern) +1 ' здесь был дефект
  
  i = InStrB(jstart, ba_search, ba_pattern, vbBinaryCompare)
  Debug.Print "второй Component в позиции массива "; i - 1 
  Debug.Print "извлечен_2 функцией: "; StrConv(MidB(ba_search, i, UBound(ba_pattern)+1), vbUnicode) ' здесь аналогично про +1
  Debug.Print "...массивом2: ";
  
  For k = i - 1 To i - 1 + UBound(ba_pattern)
    Debug.Print Chr$(ba_search(k));
  Next
  Debug.Print
End Sub
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40014811
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.,

Кстати, в общих чертах опишите и покажите пример требований к обработке найденного компонента.

с этим тоже могут быть интересные варианты, похожие на "аналог ссылок из C++"
может быть, накидаю вариант под ваш пример.

Для порядка уточните среду выплнения - исполняемый VB6 или VBA.
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40014826
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Непонятно зачем автор в ручную парсит .tlb файл?
Если для этого существует TlbInf32.dll
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015072
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ATM-TURBO 2
Дмитрий П., используй функцию StrStrA


Не могу сообразить, как использовать эту функцию в Visual Basic 6.0. Не дадите примерчик?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015103
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt
Дмитрий П., Лучше скопировать сразу весь блок в 100 байтов в строку с помощью API функции CopyMemory.

Копирования Byte в Byte получается, а Byte в String - нет :
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
Dim a As Byte, b As Byte, str As String
a = &H30
str = "1234567890"

CopyMemory b, a, 1      ' работает
CopyMemory str, a, 1    ' НЕ работает
Debug.Print str

CopyMemory str, a, 10  '  VB6 вываливается


Как использовать CopyMemory, для копирования байтов в строку?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015106
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.

Как использовать CopyMemory, для копирования байтов в строку?


Вот так например:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Option Explicit
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
            (ByVal lpDest As Any, ByVal lpSource As Any, ByVal cbCopy As Long)
 
Sub Main()

    Dim Arr(8) As Byte

    Arr(0) = 65 'A
    Arr(1) = 0

    Arr(2) = 66 'B
    Arr(3) = 0

    Arr(4) = 67 'C
    Arr(5) = 0

    Arr(6) = 68 'D
    Arr(7) = 0
 
    Dim Str1 As String

    Str1 = Space$(UBound(Arr) + 1)

    CopyMemory StrPtr(Str1), VarPtr(Arr(0)), UBound(Arr) + 1
  
    MsgBox Str1

End Sub
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015107
ATM-TURBO 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дмитрий П.
ATM-TURBO 2
Дмитрий П., используй функцию StrStrA


Не могу сообразить, как использовать эту функцию в Visual Basic 6.0. Не дадите примерчик?


https://www.cyberforum.ru/post14970478.html
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015183
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt
Вот так например:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
   ....
    Str1 = Space$(UBound(Arr) + 1)

    CopyMemory StrPtr(Str1), VarPtr(Arr(0)), UBound(Arr) + 1
  
    rem MsgBox Str1
    MsgBox "|" & Str1 & "| len=" & Len(Str1)



Ваш код выдает у мееня строку из 9ти пробелов, т.е. CopyMemory не сработала !?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015197
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.

Ваш код выдает у мееня строку из 9ти пробелов, т.е. CopyMemory не сработала !?


Сработала. Только в том коде ошибка небольшая :)


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Option Explicit
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
            (ByVal lpDest As Any, ByVal lpSource As Any, ByVal cbCopy As Long)
 
Sub Main()

    Dim Arr(8) As Byte

    Arr(0) = 65 'A
    Arr(1) = 0

    Arr(2) = 66 'B
    Arr(3) = 0

    Arr(4) = 67 'C
    Arr(5) = 0

    Arr(6) = 68 'D
    Arr(7) = 0
 
    Dim Str1 As String

    Str1 = Space$(UBound(Arr) / 2)

    CopyMemory StrPtr(Str1), VarPtr(Arr(0)), UBound(Arr) + 1
  
    MsgBox "|" & Str1 & "| len=" & Len(Str1)

End Sub
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015207
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.
...
Ваш код выдает у мееня строку из 9ти пробелов, т.е. CopyMemory не сработала !?


вы не показываете, в какую переменную копируете.
Если вы заменили определение
Dim str1 As String на показанное в стартовом посте
Dim str1 As String*100
То в таком случае показанный вариант вызова CopyMemory и не должен работать .
Фиксированные строки размещаются на стеке, и StrPtr для них температуру на Марсе показывает.
Точка начала копирования для них определяется как VarPtr(str1) + 4, где 4 - длина long переменной, хранящей длину строки...
Инициализировать такую пробелами не надо, она на всю свою длину будет инициализирована chr(0) при объявлении.
--------

Мне вот любопытно, по какой причине вы мой пост целиком проигнорировали?
В заявленном вами случае использование win api не требуется совсем
Стандартные строковые функции отлично работают с массивами.
При прямой работе с неразжатыми байтами из файла нужно использовать бинарную форму этих функций.
Просто и без api...
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015210
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

Стандартные строковые функции отлично работают с байтовыми массивами.
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015220
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.,

В чем смысл вашего кода? Если парсинг .tlb файла то есть более подходящие способы.
Например использование TLBINF32.DLL или вот пример
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015224
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Стандартные строковые функции отлично работают с байтовыми массивами.

Да, это самое правильное.
Если хочется сложностей, то есть LSet, CopyMemory, GetMem/PutMem.

Eolt
парсинг .tlb файла

А прочитать внимательнее?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015238
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
то есть, вы должны были сформулировать свой вопрос так (обратите внимание, ваш код оптимизирован):

Дмитрий П.
...
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Dim i As Integer, l As Long, str As String * 100

l = FileLen(«board.tjb»)
ReDim b(l) As Byte

get #1,,b

str = vbNullstring ' "" ' здесь вы заполняете свой буфер пробелами, хотя, может быть, лучше был бы просто String$(100, vbNullChar)
' вот так вы должны были написать, читая 50 не разжатых байт одним обращением:
str = StrConv(MidB(b, 101, 50), vbUnicode)

' а вот это ошибка, строка длиной 100 не сможет принять 100 не разжатых байтов, только 50
'For i = 100 To 200
'    str = str & Chr(b(i))
'Next i
i= InStr(str, "Component")


А нельзя ли как-то совместить некую строковую переменную с элементами с 100 по 200 массива b , чтобы избежать копирования блока в переменную (некий аналог ссылок из С++) ?


Тогда ответ бы был таким:
строку с массивом, нормальным образном - нельзя.
Но можно массив со строкой, меняя указатель на начало данных в массиве на необходимую позицию в строке.
Но в вашем случае - этого не требуется, по крайней мере, на поверхности.
Потому что строковые функции умеют работать с байтовыми массивами напрямую.

Заменять решение, построенное на стандартных функциях нужно только при особенно жестких требованиях к производительности.
Но, в любом случае, прежде чем это делать, сначала нужно выписать соответствующее задаче решение, построенное на
стандартных функциях, и только после этого смотреть, насколько же оно требует оптимизации.
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015249
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,
кстати, я сам напорол...
конечно буфер в сто символов сможет принять 100 не разжатых байт, потому что его размер - 200 байт.
должно быть
str = StrConv(MidB(b, 101, 100), vbUnicode)

мои извинения
(((;
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015262
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt
Сработала. Только в том коде ошибка небольшая :)

Да, теперь у меня тоже сработала. Спасибо

Но похоже не получится применить CopyMemory вместо побайтного копирования
Код: vbnet
1.
str = str & Chr( b(i) )


поскольку в моем массиве b нет нулей после каждого кода символа
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015275
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.

поскольку в моем массиве b нет нулей после каждого кода символа


Нули это просто кодировка Unicode, чтобы потом строку можно было вывести на экран
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015277
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Мне вот любопытно, по какой причине вы мой пост целиком проигнорировали?

Простите. Вы писали:
Код: vbnet
1.
2.
  Rem эта строка имитирует получение бинарных данных из файла
  ba_search = StrConv("В этой строке есть первый Component, и есть второй Component.", vbFromUnicode)


Нет, мой файл это не имитирует. Я неточно выразился вначале - в блоке поиска не только строки!

Я посылаю реальный файл G327.TJB Он создан утилитой CLink (ПО установки внутрисхемного контроля). Формат закрыт, но эмпирически я вычислил где и как представлена нужная мне информация. В файле описаны все цепи и пины (контактные площадки) тестируемой платы. Для каждого пина цепи есть некий блок данных где может появится строка «Component» за которой указано имя компонента (он то мне и нужен), которй мешает щупам установки опуститься на этот пин. Например:
- описание цепи «$1N309» с адреса (hex) 175D по 1986
- описание последнего пина «STP3» в этой цепи с 18BE по 1982
- блок поиска «Component» с 193D по 197D.

А цель этого поиска выдать в отчет «FU1» (как компонент который мешает щупам опуститься на STP3.)

Ваш пример сможет найти «Component» в byte массиве начиная с индекса 193D по 197D ?
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015279
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Для порядка уточните среду выплнения - исполняемый VB6 или VBA.
VB6
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015284
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий П.,

конечно поможет!

Про всякие другие уточнения я писал, предполагая, что после слова component идет ряд чисел в двоичном представлении,
которые необходимо "максимально эффективно" разобрать, вычитывая в некую структуру.
С этим могут быть отдельные заморочки, связанные с тем, как фактически записаны такие числа в бинарном представлении
в файле - в big-endian или little-endian манере.

Главное, если вы всегда читаете файл целиком, для поиска в нем "component" буфер того сорта, который вы описали - не нужен.
Но что-то похожее было бы, наверно, нужно при неполном чтении файла.
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015308
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот этот код распечатает все вхождения Component в ваш бинарный массив.
Что с этим делать дальше - вам виднее
подставьте свой путь к файлу.
(в выложенном вами файле этот код обнаруживает 13 вхождений Component)

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
Option Explicit

Sub get_file_array(ByVal sfullfilename As String, ByRef ab() As Byte)
  Dim fl As Integer
  fl = FreeFile
  Open sfullfilename For Binary Access Read Lock Write As fl
  ReDim ab(0 To LOF(fl))
  Get fl, , ab
  Close fl
End Sub


Sub test()
  Dim a() As Byte
  Rem здесь подставьте свой путь к файлу
  get_file_array "d:\D_test\G327.TJB", a
  
  Dim a_pattern() As Byte
  a_pattern = StrConv("Component", vbFromUnicode)
  Dim iPatLen As Long
  iPatLen = UBound(a_pattern) + 1&
  
  Dim iStartPos As Long, iFoundPos As Long
  iStartPos = 1
  Do
    iFoundPos = InStrB(iStartPos, a, a_pattern, vbBinaryCompare)
    Debug.Print iFoundPos - 1 ' здесь печать позиции в массиве, с которой начинается Component, на 1 меньше iFoundPos
    iStartPos = iFoundPos + iPatLen
  Loop While iFoundPos > 0
  
End Sub
...
Рейтинг: 0 / 0
Совмщение переменных разного типа
    #40015313
Дмитрий П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Главное, если вы всегда читаете файл целиком


Читаю файл целиком, но искать «Component» надо строго в неком диапазоне индексов, который определяется для каждого пина динамически.

Мой алгоритм обработки TJB такой (упрощенно):
1. ищется строка - имя 1й цепи («$1N1939»)
1.1 ищется первый пин этой цепи (строка "C2" и 4 байта 01 00 00 00 т.е. С2.1)
1.1.1 через 82 байта считываю byHead - очень важный байт (поясню, если будет интересно)
1.1.2 далее идет блок байтов где может быть «Component» - (для С2.1 его нет, т.е ничего не мешает опуститься на него)

1.2 ищется след. пин этой цепи (C2.2)
...
2. ищется строка - имя следующей цепи (например «$1N309»)
2.1 ищется первый пин этой цепи (D1.1) и его byHead т.е. определяем границы его блок поиска
...
2.3 ищется последний пин этой цепи («STP3») и его byHead т.е. получается блок поиска с 18BE по 1982 и там уже есть «Component»

3. отрабатываются остальные цепи с их пинами
...
Рейтинг: 0 / 0
25 сообщений из 40, страница 1 из 2
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Совмщение переменных разного типа
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]