Страница: 1 | 2 |
Вопрос: Странный глюк при Export As Variant
Добавлено: 28.05.05 01:02
Автор вопроса: alex
Объясните, почему данный код, при компиляции вызывает ошибку 482...
Function RetVariant Alias "RetVariant" () Export As Variant
Dim Rezult As Variant
Rezult="test"
Function=Rezult
End Function
Если закоментировать строку Function=Rezult пример нормально компилируется! В чем тут дело?
Ответы
Всего ответов: 20
Номер ответа: 1
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #1
Добавлено: 28.05.05 01:56
Все типы до 4 байт можно вернуть в eax (так и делается)
Типы 8 байт можно вернуть в паре регистров edx/eax.
Предположительно:
Тип vаriant весит 40 байт, и не в какие регистры не полезет.
Попробуй убрать Rezult в глобальные, чтобы при выходе из функции он не терялся, и возвращать не Rezult, а его адрес (as dword). И на принимающей стороне учитывай, что вернулся адрес переменной.
Номер ответа: 2
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #2
Добавлено: 28.05.05 11:28
Номер ответа: 3
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #3
Добавлено: 28.05.05 12:26
Гы Лень было лезть в msdn, чтобы уточнить, а тут в голове некстати засела цифра 40 )).
Всё верно, 16: 8 - информация, 8 - её "расшифровка", т.е. как интерпретировать.
В любом случае вернуть разом 16 байт - маловато регистров.
Номер ответа: 4
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #4
Добавлено: 28.05.05 13:57
Все равно, это не объясняет почему происходит ошибка. Если тип Variant нельзя возвращать из DLL, то данный код не должен компилироваться:
Function RetVariant Alias "RetVariant" () Export As Variant
Dim Rezult As Variant
Rezult="test"
End Function
Однако компиляция происходит без ошибок.
Странно, что можно описать функцию возвращающую тип Variant, но реально его нельзя вернуть...
Номер ответа: 5
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #5
Добавлено: 28.05.05 15:37
Если ты написал Export As Variant и компилятор это проглотил, это не значит, что можно вернуть вариант. Это всего лишь значит, что нет синтаксических ошибок. Ты сам подумай, как можно вернуть 16 байт? Значение переменной вернуть никак не удастся. Можно вернуть адрес переменной и не париться понапрасну в бесполезных попытках втиснуть в eax 16 байт.
сделай
GLOBAL Rezult AS VARIANT
Function RetVariant Alias "RetVariant" () Export As DWORD
Dim Rezult As Variant
Rezult="test"
!lea eax,Rezult
End Function
это нормально компилится. И возвращает ссылку на переменную.
Это такой же случай, когда возвращается STRING. Строку ведь невозможно вернуть в силу того что она может оказаться длиннее 8 байт, можно вернуть только адрес строки.
Номер ответа: 6
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #6
Добавлено: 28.05.05 15:39
Dim Rezult As Variant естественно не нужен, забыл удалить.
Номер ответа: 7
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #7
Добавлено: 28.05.05 15:44
А у меня выдаёт:
Error 482 in C:\PBWIN70\BIN\AUTOLOAD.BAS(12:9): Data type mismatch
Line 12: Function=Rezult
Номер ответа: 8
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #8
Добавлено: 28.05.05 15:51
Регистр тут не при чём. Компилятор должен сам уметь ложить и забирать в EAX То что нужно.
Возьми к примеру тот же Double, размер которого 64 бита. Его никак не запихнёшь в EAX, хотя функцию AS DOUBLE объявлять можно. Так что возвращай адрес переменной. Хотя я бы предпочёл передавать Variant-переменную в качестве параметра по ссылке.
Variant - это не что иное как 16-байтный UNION, у которого первые 8 байт определяют тип вторых 8 байт.
Номер ответа: 9
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #9
Добавлено: 28.05.05 15:56
Кстати, возврат результата в EAX недействителен как результат действия функции в PowerBasic.
Неправильно:
! MOV EAX,1
Правильно:
! MOV FUNCTION,1
Номер ответа: 10
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #10
Добавлено: 28.05.05 16:59
Неважно, в еах, или FUNCTION=VarPtr(..) или ещё какой способ, главное - адрес возвращать.
Номер ответа: 11
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #11
Добавлено: 28.05.05 18:38
Неважно, в еах, или FUNCTION
Для PowerBasic как раз важно. Я как то смотрел это в дизассемблере. И даже помню писал в форуме PowerBasic.com как миновать Function. Он там пишет по какому то адресу, а потом уже в EAX. Адрес не помню, глянь сам в дизассемблере.
Номер ответа: 12
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #12
Добавлено: 28.05.05 19:57
Ты не понял, неважно, каким способом будет возвращать PB адрес - как может, так пусть и возвращает. Главное - вернуть адрес переменной.
Хочет - пусть через FUNCTION=, хочет - пусть по телефону позвонит и сообщит, хочет - пусть отмылит по почте, лишь бы 32 бита попали в вызывающую программу.
Номер ответа: 13
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #13
Добавлено: 28.05.05 20:48
Можно и адрес попробовать, хотя проще передать Variant по ссылке.
Номер ответа: 14
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #14
Добавлено: 30.05.05 10:36
Мне надо использовать эту DLL в Visual Basic 6, как средствами VB разъименовать этот указатель на тип Variant, т.е. получить данные из переменной?
Номер ответа: 15
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #15
Добавлено: 30.05.05 12:25
Если ты знаешь, какого рода данные лежат в variant'е, то посмотри на это:
Dim d As Double
Dim l As Long
Dim b As Byte
Dim s As String
v = 1.5678
d = v
l = v
b = v
s = v
Debug.Print v
Debug.Print d
Debug.Print s
Debug.Print l
Debug.Print b
Т.е. решаешь, каким представлением этого варианта ты хочешь пользоваться и выбираешь соответствующего типа переменную-приёмник