Возвращение функцией массива

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Возвращение функцией массива

Сообщение pronto » 26.12.2006 (Вт) 14:48

Проиллюстрирую свой вопрос на конкретном примере.

Функции LinesIntersection передются координаты двух линий. С этим проблем нет.
Сама функция отрабатывает нормально и вычисляет координаты точки пересечения. X координаты я запоминаю в первый элемент массива p&, во второй элемент ложится Y координаты.

В PowerBasic'e есть функция VarPtr(variable_name), которая возвращает 32-битный адрес переменной, в том числе и массива. Употребляю эту функцию и LinesIntersection присваиваю ее значение.

Это я делаю из ВБ...

Код: Выделить всё
Private Type udLine
   x1 as long
   y1 as long
   x2 as long
   y2 as long
End Type

private l1 as udLine, l2 as udLine
Private uPoints(3)&, lp&

Private Declare Function LinesIntersection Lib "orel.dll" (ByRef Line1 As udLine, ByRef Line2 As udLine) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


lp = LinesIntersection(l1, l2)
Call MoveMemory(uPoints(0), lp, 8)

Picture1.Circle (uPoints(0), uPoints(1)), 3

Чего здесь не так, если Source - это адрес в памяти?
O, sancta simplicitas!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.12.2006 (Вт) 14:56

Потому что Source это не адрес в памяти. Это указатель. А если lp у тебя возвращает именно адрес в памяти, то замени

Source As Any

на

ByVal Source As Long
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 26.12.2006 (Вт) 15:39

Call MoveMemory(uPoints(0), ByVal lp, 8)
Весь мир матрица, а мы в нем потоки байтов!

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 26.12.2006 (Вт) 15:51

Чего-то не помогает... :(

uPoints(0) = 1921424
uPoints(1) = 17432836

Это явно не результат работы функции.
O, sancta simplicitas!

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

Сообщение CodeName33 » 26.12.2006 (Вт) 16:03

pronto, А в PowerBasic'е это работало?
Просто
Код: Выделить всё
Call MoveMemory(uPoints(0),ByVal lp, 8)

стабильно пишет в массив uPoints содержимое адреса lp. Если только содержимое адреса lp - удалилось после работы функции LinesIntersection...
Программисты не глючат - глючат компиляторы...

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 26.12.2006 (Вт) 16:16

в PowerBasic'e
Код: Выделить всё
   lp = VarPtr(p())
   Call MoveMemory(uPoints(0), ByVal lp, 8)
   MsgBox Str$(uPoints(0)) & " " & Str$(uPoints(1))
   LinesIntersection = VarPtr(p())         


Выдает такие же несуразные величины.
O, sancta simplicitas!

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

Сообщение CodeName33 » 26.12.2006 (Вт) 16:26

pronto, а что в это время содержится в p()? Нормальные числа?
Программисты не глючат - глючат компиляторы...

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 26.12.2006 (Вт) 16:29

может стоит уточнить, что же таки возвращает LinesIntersection? Глянув в ее описание?
Весь мир матрица, а мы в нем потоки байтов!

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 26.12.2006 (Вт) 16:54

Необходимо получить координаты точки пересечения двух линий, и если бы можно было написать "Export as POINTAPI" я бы вообще не заморачивался с этим вопросом. В программу на ВБ возможно передать только адрес этого, предварительно заполненного, массива.

может стоит уточнить, что же таки возвращает LinesIntersection? Глянув в ее описание?


Вот ее полный код

Код: Выделить всё
Function LinesIntersection Alias "LinesIntersection" (ByRef Line1 As udLine, ByRef Line2 As udLine) Export As Dword

   Local lp As Long
   
   A1 = Line1.y2 - Line1.y1
   B1 = Line1.x1 - Line1.x2
   C1 = Line1.x2 * Line1.y1 - Line1.x1 * Line1.y2  '

   A2 = Line2.y2 - Line2.y1
   B2 = Line2.x1 - Line2.x2
   C2 = Line2.y1 * Line2.x2 - Line2.x1 * Line2.y2    '


   p(0) = (B1 * C2 - B2 * C1) / (B2 * A1 - B1 * A2) '
   p(1) = (A1 * C2 - A2 * C1) / (A2 * B1 - A1 * B2) '
   
   
   lp = VarPtr(p())
   Call MoveMemory(uPoints(0), ByVal lp, 8)
   'msgbox str$(uPoints(0)) & " " & str$(uPoints(1))
 
   LinesIntersection = VarPtr(p())
End Function
O, sancta simplicitas!

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

Сообщение CodeName33 » 26.12.2006 (Вт) 17:01

pronto, ты уверен, что в PowerBasic
Код: Выделить всё
lp = VarPtr(p())

укажет на первый элемент массива?

Может быть
Код: Выделить всё
lp = VarPtr(p(0))

?
Программисты не глючат - глючат компиляторы...

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 26.12.2006 (Вт) 17:23

Точно! Спасибо тебе, CodeName33!
Заработало токи так!

Если бы не эта "опечатка" в Help'e...
To find the address of an array descriptor, use the array name with empty parentheses: VARPTR( x( ) ).
O, sancta simplicitas!

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

Сообщение CodeName33 » 26.12.2006 (Вт) 17:31

pronto, видимо там array descriptor и первый элемент массива - это разные вещи, как и в VB.
Программисты не глючат - глючат компиляторы...

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 26.12.2006 (Вт) 17:42

спешка...

Надо читать внимательнее... :)
Код: Выделить всё
DIM A$(100), b$, pA AS STRING PTR, x&
' Assume A$() is filled here
<b>pA = VARPTR(a$(0)) ' 1st element handle</b>
FOR X& = 0 TO 100
  B$ = B$ + @pA[x&] + ","
NEXT x&
O, sancta simplicitas!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 27.12.2006 (Ср) 9:42

Вот блин. Помойму проще собственную функцию для определения координат пересечения двух линий написать :roll:
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 27.12.2006 (Ср) 11:22

Помойму проще собственную функцию для определения координат пересечения двух линий написать


Может и проще, но вопрос был принципиальным.

З.Ы. Смотри мой топик выше с полным ее (функции) кодом...
O, sancta simplicitas!


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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 95

    TopList