Форум 3DNews
Вернуться   Форум 3DNews > Программирование > Программирование

Ответ Создать новую тему
Опции темы Опции просмотра
Непрочитано 08.01.2005, 22:52   [включить плавающее окно]   #1
t0p_VD
Мужской Абсолютный
Автор темы
 
Регистрация: 27.11.2003
Адрес: г. Смоленск
Функции, возвращающие массивы в VB6

Привет всем!
Уже второй день мучаюсь над вопросом..
Частью программы на VB6 является работа с комплексными числами, а точнее с комплексными матрицами. Оптимизации никакой не проводится. Важно, просто чтобы прога смогла как-то выполнять действия над матрицами, такие как сложение, умножение и пр., а также экспортировать матрицы в Excel.
Но это все было вступление.. Все это достаточно просто реализуемо, но при написании экспорта, собственно, вопрос и возник.

Private Function GetRe(Matrix()) as Single()
GetRe = GetReIm(Matrix(), "Re")
End Function

где функция GetReIm:

Private Function GetReIm(Matrix(), ReIm as String) as Single()
.
ReDim Res(1 to n, 1 to n)
.
.
GetReIm = Res
End Function

По идее функция GetRe является частным аналогом GetReIm. Как уже написано, обе функции должны возвращать матрицу чисел одинарной точности. GetReIm функционирует правильно. А вот при присвоении результата от выполнения GetReIm функции GetRe возникает ошибка "Function call on left-hand side of assignment must return variant or Object". Очевидно я просто-напросто неправильно выполняю переприсвоение. Так вот и вопрос: в чем ошибка, и как выполнить присвоение правильно?
t0p_VD вне форума  
Ответить с цитированием
Непрочитано 11.01.2005, 11:36   [включить плавающее окно]   #2
Benedict
Интересующийся
 
Регистрация: 19.06.2004
t0p_VD, рекомендуется посмотреть статью из MSDN "HOWTO: Return and Assign Arrays with Visual Basic 6.0", она же Q186423. Вкратце -
Цитата
When making array assignments, the array on the left side of the argument must me a dynamic array. Otherwise, you will receive the following compiler error:

"Can't assign to array"
И неплохо бы явно указывать тип элементов массива.
Код:
Option Explicit
Option Base 1

Private Function GetRe(Matrix() As Single) As Single()
 GetRe = GetReIm(Matrix(), "Re")
End Function

Private Function GetReIm(Matrix() As Single, ReIm As String) As Single()
 Dim n As Integer
 n = UBound(Matrix, 1)
 Dim Res() As Single
 ReDim Res(1 To n, 1 To n)
 GetReIm = Res
End Function

Private Sub Command1_Click()
 Dim M(5, 5) As Single, A() As Single
 A = GetRe(M())
End Sub
__________________
А доктор всё не едет...
Benedict вне форума  
Ответить с цитированием
Непрочитано 12.01.2005, 01:16   [включить плавающее окно]   #3
t0p_VD
Мужской Абсолютный
Автор темы
 
Регистрация: 27.11.2003
Адрес: г. Смоленск
Benedict
Цитата
When making array assignments, the array on the left side of the argument must me a dynamic array. Otherwise, you will receive the following compiler error: "Can't assign to array"
Так в том-то и дело, что массив динамический. И тип его в функции описывается, просто я его указать видать здесь забыл.. Вот полный код функций, что от твоего по сути написания не отличается.
Код:
Public Function GetRe(Matrix() As tComplex) As Single()
    GetRe = GetReIm(Matrix(), "Re")
End Function

Private Function GetReIm(Matrix() As tComplex, ReIm As String) As Single()
    Dim H As Integer, W As Integer
    Dim i As Integer, j As Integer
    Dim Res() As Single
    
    H = UBound(Matrix, 1) - LBound(Matrix, 1) + 1
    W = UBound(Matrix, 2) - LBound(Matrix, 2) + 1
    
    ReDim Res(1 To H, 1 To W) As Single
    
    Select Case UCase(ReIm)
    Case "RE"
        For i = 1 To H
            For j = 1 To W
                Res(i, j) = Matrix(i, j).Re
            Next
        Next
    Case "IM"
        For i = 1 To H
            For j = 1 To W
                Res(i, j) = Matrix(i, j).Im
            Next
        Next
    End Select
    
    GetReIm = Res
End Function
Может я все-же чего-либо не заметил, что у меня появляется ошибка?
P.S. При вызове массив, в который помещается результат, тоже описан как динамический (типа того
Код:
Dim A() as single
)
t0p_VD вне форума  
Ответить с цитированием
Непрочитано 12.01.2005, 03:02   [включить плавающее окно]   #4
Benedict
Интересующийся
 
Регистрация: 19.06.2004
В том виде, что ты привёл, код работает без замечаний.
__________________
А доктор всё не едет...
Benedict вне форума  
Ответить с цитированием
Непрочитано 13.01.2005, 14:51   [включить плавающее окно]   #5
Barloggg
Мужской Продвинутый
 
Аватар для Barloggg
 
Регистрация: 11.03.2003
Адрес: Тьмутаракань2, лен. обл
В дельфе это лечится кучей способов.
1. передаешь не сам массив а поинтер на него
2. создаешь новый тип переменной с динамическим массивом внутри (например запись) и передаешь его целиком
3. создаешь объект и передаешь его
4. извращаешься через задницу... например через поток или файл )) или через глобальные переменные

надеюсь меня можно понять...
Barloggg вне форума  
Конфигурация ПК
Ответить с цитированием
Непрочитано 15.01.2005, 09:26   [включить плавающее окно]   #6
t0p_VD
Мужской Абсолютный
Автор темы
 
Регистрация: 27.11.2003
Адрес: г. Смоленск
Barloggg
Цитата
В дельфе это лечится кучей способов
В данном случае речь не про Delphi. Идеальным было-бы действительно передача указателя. Кстати, это дейстивтельно возможно. Об этом я только что узнал. Ранее в Basic была функция VarPtr. Я думал почему-то в VB ее нету. Оказывается ошибся. Помимо этого есть и функция VarPtrArray, возвращающая адрес массива (не понятно только, первого элемента, или указателя на структуру описания). Правда объявить ее надо вот так (если кому интересно):
Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() as Any) As Long (для VB6).
Помимо этого есть и такие полезные функции ObjPtr, StrPtr, VarPtrStringArray. Нда.. В общем от жизни я немного подотстал..
Цитата
создаешь объект и передаешь его
В смысле? И этот объект, как одно из свойств - массив содержит что-ли? Не понял я..
t0p_VD вне форума  
Ответить с цитированием
Непрочитано 15.01.2005, 11:59   [включить плавающее окно]   #7
Benedict
Интересующийся
 
Регистрация: 19.06.2004
t0p_VD, VarPtr() описана в библиотеке VBA, но скрыта (т.е. можно использовать без явного описания). Чтобы её увидеть, надо в Object Browser-е включить показ скрытых членов. Приведённое тобой описание VarPtrArray всего лишь создаёт псевдоним VarPtr. В случае её вызова возвращается адрес на структуру SAFEARRAY. Чтобы получить адрес первого элемента, надо запросить его в явном виде (как ни удивительно ):
Код:
 Dim MyArr(10) As Single, pMyArr As Long
 pMyArr = VarPtr(MyArr(LBound(MyArr)))
Чтобы немного "догнать жизнь", рекомендуется к прочтению Q199824 и глава 6 из книги "Win32 API Programming with Visual Basic", by Steven Roman. Последняя не совсем про массивы, но снимает ОЧЕНЬ много вопросов. Всё это есть в MSDN Library.

P.S. Я слабо понял, как это относится к первоначальной теме.
__________________
А доктор всё не едет...

Последний раз редактировалось Benedict; 15.01.2005 в 12:03.
Benedict вне форума  
Ответить с цитированием
Непрочитано 15.01.2005, 21:06   [включить плавающее окно]   #8
t0p_VD
Мужской Абсолютный
Автор темы
 
Регистрация: 27.11.2003
Адрес: г. Смоленск
Benedict
Цитата
рекомендуется к прочтению Q199824
Именно оттуда описание VarPtrArray и взято..
Цитата
Я слабо понял, как это относится к первоначальной теме.
Уже никак..
t0p_VD вне форума  
Ответить с цитированием
Непрочитано 25.01.2005, 11:52   [включить плавающее окно]   #9
Barloggg
Мужской Продвинутый
 
Аватар для Barloggg
 
Регистрация: 11.03.2003
Адрес: Тьмутаракань2, лен. обл
t0p_VD.
Правильно, создаешь объект в котором одно из свойств - этот динамический массив и таскаешь указатель на объект.
В Дельфе это явным образом не разделяется и поэтому у меня до сих пор путаница, что считать объектом, а что "умным" указателем.
Надо бы мне поработать над моей терминологией...
Barloggg вне форума  
Конфигурация ПК
Ответить с цитированием
Ответ Создать новую тему

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 12:51. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 2000-2017 3DNews. All Rights Reserved.
Администрация 3DNews требует соблюдения на форуме правил и законов РФ
Серверы размещены в Hostkey