Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Power Basic

Страница: 1 | 2 |

 

  Вопрос: Странный глюк при Export As Variant Добавлено: 28.05.05 01:02  

Автор вопроса:  alex

Объясните, почему данный код, при компиляции вызывает ошибку 482...

#Compile Dll
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-сайт: sharpc.livejournal.com
 Профиль | | #2
Добавлено: 28.05.05 11:28
Тип vаriant весит 40 байт
Откуда дровишки? Всегда думал, что 16.

Ответить

Номер ответа: 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, то данный код не должен компилироваться:

#Compile 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 байт.
сделай

#Compile Dll
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-сайт: basicproduction.nm.ru
 Профиль | | #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-сайт: basicproduction.nm.ru
 Профиль | | #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-сайт: basicproduction.nm.ru
 Профиль | | #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-сайт: basicproduction.nm.ru
 Профиль | | #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-сайт: basicproduction.nm.ru
 Профиль | | #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 v As 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


Т.е. решаешь, каким представлением этого варианта ты хочешь пользоваться и выбираешь соответствующего типа переменную-приёмник

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам