powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Safearray и ReDim массива
9 сообщений из 9, страница 1 из 1
Safearray и ReDim массива
    #35700088
Avtopic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!

В процедуре имею указатель на Safearray 2-х мерного массива.
Как с помощью этого указателя сделать ReDim массива, не зная тип массива?

Сам делаю так (криво):
Делаю клон массива

Dim TmpArray () As ???

GetMem4 ppMoyArray, ppTmpArray
Делаю ReDim TmpArray
и уничтожаю клон.

Но, не зная тип массива, вынужден в процедуру передавать тип и иметь пустые TmpArray для всех типов, которые предвидятся, что будут использованы в будущем.

Хочется по универсальнее.

Можно или нет получить массив, зная указатель на Safearray?
(включая UDT).

Спасибо!
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35700443
Зри в корень
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35700635
Avtopic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Зри в корень,

msdn:
You can change only the least significant dimension of an array

а у меня 2-х мерный массив
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35701078
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если это .NET, то вам в другой топик.
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35701105
Avtopic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NET, это не .NET.
Это VB6 + Api
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35703503
Зри в корень
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Avtopicmsdn:
You can change only the least significant dimension of an array

а у меня 2-х мерный массивУ Redim Preserve поведение точно такое же (потому что используется SafeArrayRedim). Или не нужен Preserve?

Вопрос такой - а указатель на SAFEARRAY откуда берётся, не искусственное ли это условие? К массивам, загнанным в вариант, Redim применим, и вполне просто:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Sub Redim2D( _
   v As Variant, _
   ByVal lLBound1 As Long, ByVal lUBound1 As Long, _
   ByVal lLBound2 As Long, ByVal lUBound2 As Long)
 ReDim v(lLBound1 To lUBound1, lLBound2 To lUBound2)
End Sub

Sub Test()
 Dim c() As Long
 ReDim c( 0  To  3 ,  0  To  2 ) As Long
 Debug.Print LBound(c,  1 ), UBound(c,  1 ), LBound(c,  2 ), UBound(c,  2 )
 Redim2D c,  7 ,  12 , - 2 ,  4 
 Debug.Print LBound(c,  1 ), UBound(c,  1 ), LBound(c,  2 ), UBound(c,  2 )
End Sub
Правда, с UDT проблемка: их надо описывать в Type Library (самописной, либо поместив описание UDT в класс с Instancing > 1 (Private) ).
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35704231
Avtopic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Preserve не нужен.

Нужен Redim и первой и второй размерности, не зная тип массива, по указателю.

Покорявшись в апи функциях удалось сделать для 1 и 2-х мерного массива любого типа (по-моему любого)

Код: plaintext
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.
Public Function RedimPtr(ByVal ppArray As Long, ByVal LBound1 As Long, ByVal UBound1 As Long, _
                                       Optional ByVal LBound2 As Long, Optional ByVal UBound2 As Long) As Long

    Dim DDims As Long

    GetMem4 ppArray, VarPtr(RedimPtr)
    If RedimPtr =  0  Then Exit Function
    GetMem2 RedimPtr, VarPtr(DDims)

    If DDims =  1  Then

        Call SafeArrayDestroyData(ByVal RedimPtr)
        PutMem4 RedimPtr +  16 , UBound1 - LBound1 +  1        
        PutMem4 RedimPtr +  20 , LBound1                     
        Call SafeArrayAllocData(ByVal RedimPtr)

    ElseIf DDims =  2  Then

        Call SafeArrayDestroyData(ByVal RedimPtr)
        PutMem4 RedimPtr +  16 , UBound2 - LBound2 +  1        
        PutMem4 RedimPtr +  20 , LBound2                     

        PutMem4 RedimPtr +  24 , UBound1 - LBound1 +  1        
        PutMem4 RedimPtr +  28 , LBound1                     
        Call SafeArrayAllocData(ByVal RedimPtr)

    Else

        RedimPtr =  0 
        MsgBox "   Wrong Array dimensions!        " & Chr( 13 ) & "   Only one or two dimension Arrays supported! ", vbCritical, "Error"

    End If
End Function
первый аргумент указатель на массив, (или легко переделать, если прямо имеем указатель на SafeArray массива)
остальные аргументы по названиям, легко понять, что из себя представляют.
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35705223
Зри в корень
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Avtopic,
вроде бы должно работать, раз в дескрипторе массива меняются только размерности.

На правах мыслей вслух. Есть не совсем понятный момент:Описание SafeArrayDestroyDataThis function is typically used when freeing safearrays that contain elements with data types other than variants . ... Safe arrays of variant will have VariantClear called on each member ...Описание VariantClearIn certain cases, it may be preferable to clear a variant in code without calling VariantClear. ... You must call VariantClear if a VT_type is received but cannot be handled. Safearrays of variant will also have VariantClear called on each member. Using VariantClear in these cases ensures that code will continue to work if Automation adds new variant types in the future.Так почему "обычно используется ... другими, нежели вариант"? Нельзя использовать с элементами типа вариант? Вряд ли. VariantClear вызывается для каждого элемента, что ещё надо? Или здесь речь о потере производительности, которую можно избежать?
...
Рейтинг: 0 / 0
Safearray и ReDim массива
    #35705516
Avtopic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Зри в корень
Описание SafeArrayDestroyDataThis function is typically used when freeing safearrays that contain elements with data types other than variants . ... Safe arrays of variant will have VariantClear called on each member ...Так почему "обычно используется ... другими, нежели вариант"? Нельзя использовать с элементами типа вариант? Вряд ли. VariantClear вызывается для каждого элемента, что ещё надо? Или здесь речь о потере производительности, которую можно избежать?
Я это у них понял так (если не ошибаюсь):

если только менять размерность и использовать SafeArrayAllocData, то останется в памяти мусор - старые данные, и поэтому ми сперва освобождаем память, используя SafeArrayDestroyData, не так ли, но:

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


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