Строка и байтоввый массив

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Строка и байтоввый массив

Сообщение Antonariy » 06.04.2007 (Пт) 9:56

Можно ли сделать так, чтобы строковая переменная и байтовый массив указывали на одну и ту же облать памяти? То есть изменил данные в x() As Byte - изменились данные в y As String.
Лучший способ понять что-то самому — объяснить это другому.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.04.2007 (Пт) 10:26

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

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 06.04.2007 (Пт) 10:29

Можно попробовать так:
Декларации:
Код: Выделить всё
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long

Private Type SAFEARRAYBOUND
    cElements As Long
    lLbound As Long
End Type
Private Type SAFEARRAY
    cDims As Integer
    fFeatures As Integer
    cbElements As Long
    cLocks As Long
    pvData As Long
    Bounds(0 To 0) As SAFEARRAYBOUND
End Type


Init:
Код: Выделить всё
Dim SA as SAFEARRAY,MyArray() As Byte
With SA
  .cbElements = 1
  .cDims = 1
  .Bounds(0).lLbound = 0 'Lbound
  .Bounds(0).cElements = 1 'Ubound
  .pvData = 0 'Pointer Here
End With
CopyMemory ByVal VarPtrArray(MyArray), VarPtr(SA), 4


Destroy:
Код: Выделить всё
CopyMemory ByVal VarPtrArray(MyArray), CLng(0), 4


Эта конструкция позволяет сделать массив где угодно, только вот как выйди на адрес, где хранятся символы строки я не знаю.
Программисты не глючат - глючат компиляторы...

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 06.04.2007 (Пт) 10:30

Опоздал я :) Да интежеровый массив, строки вроде как в Unicode, или байтовый, но *2
Программисты не глючат - глючат компиляторы...

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 06.04.2007 (Пт) 10:45

Эта конструкция позволяет сделать массив где угодно, только вот как выйди на адрес, где хранятся символы строки я не знаю.

StrPtr
Изображение

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 06.04.2007 (Пт) 11:10

GSerg писал(а):modSAFEARRAY в кирпичах.
Только интеджеровый массив тогда.
Насчет интеджерового массива не понял, но все получилось так:
Код: Выделить всё
Dim arrMain As String
Dim arr1() As Byte
    arrMain = "12345"
    CreateSAFEARRAY ArrPtr(arr1), 2, StrPtr(arrMain), 1, Len(arrMain)
    arr1(1) = 50
    Debug.Print arrMain
    DestroySAFEARRAY ArrPtr(arr1)
Благодарю :)
Лучший способ понять что-то самому — объяснить это другому.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.04.2007 (Пт) 11:26

Каждый символ в строке занимает 2 байта, и массив должен быть Integer.
Что сделал ты и почему это получилось, пока непонятно, но так делать не надо.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 06.04.2007 (Пт) 12:14

Я сначала сделал CreateSAFEARRAY ArrPtr(arr1), 1, StrPtr(arrMain), 1, Len(arrMain) и получил именно массив строки, в которой символ занимает 2 байта (в нем оказалось пол-строки), в общем много лишних нулей, и, увидев их, как раз вспомнил про эти байты. Подумал, почему бы не попробовать длину 2? Попробовал, IDE не дрогнула.

На самом деле все понятно. Каждый элемент массива arr1 ссылается на первый байт каждого символа строки. Если сделать Debug.Print VarPtr(arr1(1)), VarPtr(arr1(2)), то можно увидеть, что их адреса отличаются на 2. В общем все это будет корректно работать пока в строке не всплывет юникодный символ - замена одного байта из двух даст не тот результат.

Интересно, как с этим массивом будет себя вести CopyMemory...
Лучший способ понять что-то самому — объяснить это другому.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 06.04.2007 (Пт) 12:27

Antonariy писал(а):Интересно, как с этим массивом будет себя вести CopyMemory...


А ты кинь модуль со всеми декларациями, а не отдельную вырезку - посмотрим...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 06.04.2007 (Пт) 13:06

Модуль с декларациями в кирпичах, весь остальной код - это и есть вырезка, за исключением sub и end sub. :)

Проверил. Очень непредсказуемые резултаты получаются.
Лучший способ понять что-то самому — объяснить это другому.


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

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

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 102

    TopList