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

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

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

Dim TmpArray () As ???

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

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

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

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

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

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

а у меня 2-х мерный массив
...
Рейтинг: 0 / 0
08.12.2008, 20:31
    #35701078
VladConn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
Если это .NET, то вам в другой топик.
...
Рейтинг: 0 / 0
08.12.2008, 20:54
    #35701105
Avtopic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
NET, это не .NET.
Это VB6 + Api
...
Рейтинг: 0 / 0
09.12.2008, 17:31
    #35703503
Зри в корень
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
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
10.12.2008, 01:34
    #35704231
Avtopic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
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
10.12.2008, 13:17
    #35705223
Зри в корень
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
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
10.12.2008, 14:37
    #35705516
Avtopic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Safearray и ReDim массива
Зри в корень
Описание 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
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Safearray и ReDim массива / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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