Если ты используешь только числа, тогда используй тип DOUBLE и все будет в поряде. Но при этом всегда нужен byVal чтоб не было матюков насчет несовместимости типов данных. Пример :
Function Test (byVal p As DOUBLE) AS DOUBLE
Test=Sin(p)
End Function
В объявлении функций с помощью Declare для параметров можно использовать тип ANY. Т.е. если так вот объявить переменную, то вызывать функцию можно с разными по типу параметрами, в функцию же будет передаваться как раз указатель.
Проблема в том, как уже внутри функции "понять" что передали: например LONG или DOUBLE. Ссылка ссылкой, но данные то разной длины!
Так что здесь видимо придётся (как и предлагается в хелпе) передавать ещё один параметр - для определения типа данных. А это уже не столь эффективно/эффектно.
(И если, не путаю, ANY можно пользовать только в Declare, т.ч. ещё надо чтобы и сама функция была "снаружи", в DLL-ке).
(И если, не путаю, ANY можно пользовать только в Declare, т.ч. ещё надо чтобы и сама функция была "снаружи", в DLL-ке).
Не обязательно, можно итак использовать ANY, но
тип данных конечно надо сообщать
#COMPILE EXE
#DIM ALL
%word=2
%dword=4
%double=8
%ext=10
'****************************************************************
DECLARE FUNCTION fake (BYVAL p AS ANY,BYVAL t AS LONG ) AS DOUBLE
'****************************************************************
FUNCTION Test (BYVAL p AS DWORD, BYVAL t AS LONG) AS DOUBLE
LOCAL lpW AS WORD PTR
LOCAL lpDW AS DWORD PTR
LOCAL lpDBL AS DOUBLE PTR
LOCAL lpEXT AS EXT PTR
SELECT CASE t
CASE %word
lpW = p : FUNCTION = @lpW
CASE %dword
lpDW =p : FUNCTION = @lpDW
CASE %double
lpDBL=p : FUNCTION = @lpDBL
CASE %ext
lpEXT=p : FUNCTION = @lpEXT
END SELECT
END FUNCTION
'*****************************************
FUNCTION PBMAIN () AS LONG
LOCAL w AS WORD :w =1
LOCAL dw, func AS DWORD :dw=1
LOCAL dbl,dblRes AS DOUBLE :dbl=1.001
LOCAL ex,extRes AS EXT :ex =1.0001
func=CODEPTR(Test)
CALL DWORD func USING fake(BYVAL VARPTR(w) ,%word) TO dblRes : ? FORMAT$(dblRes,18)
CALL DWORD func USING fake(BYVAL VARPTR(dw) ,%dword) TO dblRes : ? FORMAT$(dblRes,18)
CALL DWORD func USING fake(BYVAL VARPTR(dbl),%double) TO dblRes : ? FORMAT$(dblRes,18)
CALL DWORD func USING fake(BYVAL VARPTR(ex) ,%ext) TO extRes : ? FORMAT$(extRes,18)
END FUNCTION
FUNCTION PBMAIN () AS LONG
LOCAL sTemp AS STRING
LOCAL s AS SINGLE : s=1.0000001
LOCAL d AS DOUBLE : d=1.000000000000001
LOCAL e AS EXTENDED : e=1.00000000000000001
sTemp= "Single ="+FORMAT$(s,18)+$CRLF
sTemp=sTemp+"Double ="+FORMAT$(d,18)+$CRLF
sTemp=sTemp+"Extended="+FORMAT$(e,18)
? sTemp,64,"Report"
END FUNCTION
просто STR$ и FORMAT$ перед тем как отображать что либо
конвертирует данные в EXTENDED, отсюда и чудеса из мусора
округления, т.е. если сам тип данных не поддерживает такой точности, то в принципе до барабана, что появляеться мусор после конвертации. В случае
если мы назначаем в EXTENDED 0.0001 то сами же игнорируем точность после 1, т.е. нужна точность
значит и назначать надо соответственно до нужного знака =0.00001000000000001
Variant использовать не хочется, т.к. считается, что он слишком тормозной.
Скорее массивный, 16 байт всё таки: 8 байт флаг и 8 байт объединение. Оставь 8-байтовое объединение, а флаг можно вообще вынести за процедуру.
Не скажу что это что-то оригинальное, но микрософт то именно так поступает.
#Compile Exe
#Include "WIN32API.INC"
Global FlgType As Byte
Union WDF
Wrd As Word
 wd As Dword
Flt As Double
End Union
Sub Show_WDF(Number As WDF)
Select Case FlgType
Case 0
MsgBox Str$(Number.Wrd),,"Wrd"
Case 1
MsgBox Str$(Number.Dwd),,"wd"
Case 2
MsgBox Str$(Number.Flt),,"Flt"
End Select
End Sub
Function PBMain
Dim SendMe As WDF
SendMe.Wrd=65535
Show_WDF SendMe