CodeName33 писал(а):CopyMemory не прокатит если это массив из пльзовательского типа данных. Кидать будет.
CodeName33 писал(а):>Почему? Объясни плз
Раньше не мог понять, чего у меня прога одна кидает иногда. А причина была в том, что когда передаёшь в API функцию параметр A(1), то если A() массив обычных типов (Int, Long) то VB передаёт реальный адрес первого элемента, а если он массив сложных пользовательских типов данных (ещё с подтипами внутри), то VB почему-то копировал один передаваемый элемент в отдельную область памяти, и передавал его адрес. Зачаем я так и не понял. Но если самому докопаться до реального адреса массива (VarPtrArray(A()), а потом через структуры SAFEARRAY), то можно и через CopyMemory двигать.
tyomitch писал(а):Approximator, CodeName33 прав
tyomitch писал(а): - я просто совсем выпустил из виду эту "особенность" VB. Если по ссылке передаётся структура, содержащая строки и/или паддинг, то VB создаёт её временную копию, и передаёт в функцию именно копию.
Public Function AnyPtr(ByRef vVar As Variant) As Long
CopyMem VarPtr(AnyPtr), VarPtr(vVar) + 1, 1
If AnyPtr = 64 Or AnyPtr = 96 Then CopyMem VarPtr(AnyPtr), VarPtr(vVar) + 8, 4
End Function
tyomitch писал(а):
- Код: Выделить всё
CopyMemory ByVal VarPtr(Massiv(i)), ByVal VarPtr(Massiv(i + 1)), LenB(Massiv(LBound(Massiv))) * (UBound(Massiv) - i)
CodeName33 писал(а):>CopyMemory ByVal VarPtr(Massiv(i)), ByVal VarPtr(Massiv(i + 1)), LenB(Massiv(LBound(Massiv))) * (UBound(Massiv) - i)
У меня в своё время так не прокатило. Он в VarPtr тоже передавал копию элемента и не давал адрес самого массива. Хотя может я и ошибаюсь...
Public Function SomeTypePtr(byref vSomeType as SomeType, optional byval vPleaseIgnoreMe as Long=0)as Long
CopyMem VarPtr(SomeTypePtr), VarPtr(vPleaseIgnoreMe)-4,4
End Function
Public Function SomeTypeArrPtr(byref vSomeTypeArr() as SomeType, optional byval vPleaseIgnoreMe as Long=0)as Long
CopyMem VarPtr(SomeTypeArrPtr), VarPtr(vPleaseIgnoreMe)-4,4
End Function
CodeName33 писал(а):У меня в своё время так не прокатило. Он в VarPtr тоже передавал копию элемента и не давал адрес самого массива. Хотя может я и ошибаюсь...
Option Explicit
Private Declare Function AnyPtr Lib "msvbvm60" Alias "VarPtr" (v As Any) As Long
Private Declare Function TypePtr Lib "msvbvm60" Alias "VarPtr" (v As NastyType) As Long
Type NastyType
m1 As Byte
m2 As String * 6
m3 As String
End Type
Private t As NastyType
Sub Main()
Debug.Print Len(t), LenB(t)
Debug.Print VarPtr(t), VarPtr(t.m1)
Debug.Print AnyPtr(t), TypePtr(t)
End Sub
tyomitch писал(а):AnyPtr имхо здесь не прокатит, т.к. не удастся так легко засунуть UDT в вариант. Хотя идея любопытная, буду иметь в виду.
VarPtr, с другой стороны, работает правильно - возвращает адрес самой структуры, а не копии. В крайнем случае, можно брать VarPtr от первого элемента.
Я проверял всё это в топике, где мы с Ennor-ом обсуждали вызов юникодных функций, посмотри там.
Public Function <ИмяРек>(byref vAny as Variant)as Long
dim lRes as Long
<прежнее тело функции>
CopyMem VarPtr(lRes), VarPtr(vAny)+8,4
<ИмяРек>=lRes
End Function
tyomitch писал(а):Approximator, ты имхо не понял главного
VarPtr здесь работает прекрасно, зачем ещё что-то изобретать?
Type MyType
Sa(1 to 2) as String
End Type
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (D As Any, S As Any, ByVal c As Long)
Сейчас этот форум просматривают: Google-бот и гости: 3