and edit the test code to reflect where you put the dll
the code below is adapted from code posted by sapero in another forum.
the thing to watch out for when using an activex dll in this fashion is that if the dll is changed - functions added or deleted
then you will have to revise the interface code
Code: Select all
Macro DEFINE_GUID(n,d1,d2,d3,b1,b2,b3,b4,b5,b6,b7,b8)
n.GUID\Data1=d1
n\Data2=d2
n\Data3=d3
n\Data4[0]=b1
n\Data4[1]=b2
n\Data4[2]=b3
n\Data4[3]=b4
n\Data4[4]=b5
n\Data4[5]=b6
n\Data4[6]=b7
n\Data4[7]=b8
EndMacro
DEFINE_GUID(TLB_DLLXnumbers, $F0F97DA7, $FCDC, $4DF2, $A9, $EC, $13, $3A, $CC, $C0, $2C, $CF)
DEFINE_GUID(CLSID_Xnumbers, $7BE8D542, $22B1, $453B, $92, $F2, $72, $D8, $D1, $BE, $BE, $A0)
DEFINE_GUID(CLSID_Complex, $DDA69B44, $8DF5, $4853, $81, $AA, $75, $78, $92, $52, $FE, $61)
DEFINE_GUID(IID_Complex, $8AC07909, $BF6A, $4109, $8C, $BD, $5C, $8B, $72, $88, $17, $AB)
DEFINE_GUID(IID_Xnumbers, $DF877274, $97EB, $48FF, $9D, $7E, $FE, $83, $05, $7E, $53, $AD)
Interface IXnumbers
; IUnknown
QueryInterface(riid.GUID, *ppv)
AddRef()
Release()
; IDispatch
GetTypeInfoCount(*pdwctinfo)
GetTypeInfo(itinfo.l, lcid.l,*lpITypeInfo)
GetIDsOfNames(riid.GUID, *rgszNames, cNames.l, lcid.l, *rgDispId)
Invoke(dispidMember.l, riid.GUID, lcid.l, wFlags.l, pdispparams.DISPPARAMS, *pvarResult, *pexcepinfo, *pdwArgErr_pUINT)
; IXnumbers
get_DigitsMax(*lpInt)
put_DigitsMax(max.l)
get_Cplx(*lpIComplex)
xLog(x.VARIANT, base.VARIANT, DgtMax.VARIANT, result.VARIANT)
x2Pi(DgtMax.VARIANT, result.VARIANT)
xPi(DgtMax.VARIANT, result.VARIANT)
xPi2(DgtMax.VARIANT, result.VARIANT)
xPi4(DgtMax.VARIANT, result.VARIANT)
xLN2(DgtMax.VARIANT, result.VARIANT)
xE(DgtMax.VARIANT, result.VARIANT)
xLN10(DgtMax.VARIANT, result.VARIANT)
xEu(DgtMax.VARIANT, result.VARIANT)
xSin(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xCos(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xTan(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAtan(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAsin(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAcos(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAbs(x.VARIANT, result.VARIANT)
xMult(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAdd(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xInv(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDiv(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDivRem(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDivInt(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xNeg(a1.VARIANT, result.VARIANT)
xSub(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xExp(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xRoot(x.VARIANT, n.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSqr(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xLn(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xExpBase(a.VARIANT, x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xPow(x.VARIANT, n.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSum(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xProd(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xQmean(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xGmean(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDgt(num.VARIANT, result.VARIANT)
xFact(n.VARIANT, DgtMax.VARIANT, result.VARIANT)
xComb(n.VARIANT, k.VARIANT, DgtMax.VARIANT, result.VARIANT)
xPerm(n.VARIANT, k.VARIANT, DgtMax.VARIANT, result.VARIANT)
xInt(a.VARIANT, result.VARIANT)
xComp(a.VARIANT, b.VARIANT, result.VARIANT)
xAngleCompl(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
isXnumber(x.VARIANT, *plVarBool) ;/*VARIANT_BOOL*/
xGCD(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xLCM(a1.VARIANT, a2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDec(x.VARIANT, result.VARIANT)
xFract(x.VARIANT, DigitMax.VARIANT, result.VARIANT)
xMDet(Mat.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMInv(Mat.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMMod(Mat.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMMult(Mat1.VARIANT, Mat2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMSub(Mat1.VARIANT, Mat2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMAdd(Mat1.VARIANT, Mat2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xProdScal(v1.VARIANT, v2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xGaussJordan(Mat.SAFEARRAY, n.VARIANT, m.VARIANT, Det.VARIANT, algo.VARIANT, DgtMax.VARIANT)
xSysLin(Ma.VARIANT, Mb.VARIANT, DgtMax.VARIANT, result.VARIANT)
xRegLinCovar(y.VARIANT, x.VARIANT, coeff.VARIANT, DgtMax.VARIANT, *lpVarBoolIntcpt, result.VARIANT)
xRegLinCoeff(y.VARIANT, x.VARIANT, DgtMax.VARIANT, Intcpt.VARIANT, result.VARIANT)
xRegLinStat(y.VARIANT, x.VARIANT, coeff.VARIANT, DgtMax.VARIANT, *Intcpt, result.VARIANT)
xRoundr(x.VARIANT, dgt.VARIANT, result.VARIANT)
xDgtS(x.VARIANT, result.VARIANT)
xRound(x.VARIANT, Dec.VARIANT, result.VARIANT)
xFormat(str.VARIANT, DgtGrp.VARIANT, *lpBstr)
xUnformat(s.VARIANT, *lpBstr)
xLRE(q.VARIANT, c.VARIANT, noSD.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMBAB(a.VARIANT, b.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMPow(Mat.VARIANT, n.VARIANT, DgtMax.VARIANT, result.VARIANT)
xProdVect(v1.VARIANT, v2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMLU(Mat.VARIANT, Pivot.VARIANT, DgtMax.VARIANT, result.VARIANT)
xRegLinEval(coeff.VARIANT, x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSinh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xCosh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xTanh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAsinh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAcosh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAtanh(x.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSplit(x.VARIANT, result.VARIANT)
xCvExp(mantissa.VARIANT, exponent.VARIANT, result.VARIANT)
xFact2(n.VARIANT, DgtMax.VARIANT, result.VARIANT)
MatrixSort(a.VARIANT, IndexCol.VARIANT, Order.VARIANT, *lpCaseSensitive)
xEval(*lpBstrFormula, x.VARIANT, DgtMax.VARIANT, Angle.VARIANT, result.VARIANT)
xCDbl(x.VARIANT, result.VARIANT)
xMLL(Mat.VARIANT, DgtMax.VARIANT, result.VARIANT)
xAngleCv(angle.VARIANT, Us.VARIANT, Ut.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMax(a.VARIANT, result.VARIANT)
xMin(a.VARIANT, result.VARIANT)
xPowMod(a.VARIANT, p.VARIANT, m.VARIANT, DgtMax.VARIANT, result.VARIANT)
xIsOdd(a.VARIANT, *lpis)
xIsSquare(n.VARIANT, *lpis)
xDiophEqu(a.VARIANT, b.VARIANT, c.VARIANT, result.VARIANT)
xTrunc(x.VARIANT, result.VARIANT)
xStDev(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xStDevp(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xVar(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xVarp(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMean(a.VARIANT, DgtMax.VARIANT, result.VARIANT)
EndInterface
Interface IComplex
; IUnknown
QueryInterface(riid.GUID, *ppv)
AddRef()
Release()
; IDispatch
GetTypeInfoCount(*pdwctinfo)
GetTypeInfo(itinfo.l, lcid.l,*lpITypeInfo)
GetIDsOfNames(riid.GUID, *rgszNames, cNames.l, lcid.l, *rgDispId)
Invoke(dispidMember.l, riid.GUID, lcid.l, wFlags.l, pdispparams.DISPPARAMS, *pvarResult, *pexcepinfo, *pdwArgErr_pUINT)
; IComplex
sAdd(z1.VARIANT, z2.VARIANT, result.VARIANT)
sSub(z1.VARIANT, z2.VARIANT, result.VARIANT)
sMult(z1.VARIANT, z2.VARIANT, result.VARIANT)
sDiv(z1.VARIANT, z2.VARIANT, result.VARIANT)
sMultS(z.VARIANT, s.VARIANT, result.VARIANT)
sAbs(z.VARIANT, result.VARIANT)
sPolar(z.VARIANT, result.VARIANT)
sRect(z.VARIANT, result.VARIANT)
sRoot(z.VARIANT, n.VARIANT, k.VARIANT, result.VARIANT)
sPow(z.VARIANT, n.VARIANT, result.VARIANT)
sInv(z.VARIANT, result.VARIANT)
sNeg(z.VARIANT, result.VARIANT)
sConj(z.VARIANT, result.VARIANT)
sLn(z.VARIANT, result.VARIANT)
sLog10(z.VARIANT, result.VARIANT)
sExp(z.VARIANT, result.VARIANT)
sSqr(z.VARIANT, k.VARIANT, result.VARIANT)
sIsZero(z.VARIANT, Tiny.VARIANT, *lpBool)
xAbs(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSub(z1.VARIANT, z2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xConj(z.VARIANT, result.VARIANT)
xAdd(z1.VARIANT, z2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xMult(z1.VARIANT, z2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xDiv(z1.VARIANT, z2.VARIANT, DgtMax.VARIANT, result.VARIANT)
xInv(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xNeg(z.VARIANT, result.VARIANT)
xPolar(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xRect(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xRoot(z.VARIANT, n.VARIANT, k.VARIANT, DgtMax.VARIANT, result.VARIANT)
xPow(z.VARIANT, n.VARIANT, DgtMax.VARIANT, result.VARIANT)
xLn(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xLog10(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xExp(z.VARIANT, DgtMax.VARIANT, result.VARIANT)
xSqr(z.VARIANT, k.VARIANT, DgtMax.VARIANT, result.VARIANT)
xIsZero(z.VARIANT, Tiny.VARIANT, DgtMax.VARIANT, *lpBool)
EndInterface
;enum variantbool
;#VARIANT_TRUE = 65535
#VARIANT_FALSE = 0
; type of variant variable: VARIANT.vt
;enum VARENUM
#VT_EMPTY = 0
#VT_NULL = 1
#VT_BOOL = 11
#VT_I1 = 16
#VT_I2 = 2
#VT_I4 = 3
#VT_I8 = 20
#VT_INT = 22
#VT_INT_PTR = 37
#VT_UI1 = 17
#VT_UI2 = 18
#VT_UI4 = 19
#VT_UI8 = 21
#VT_UINT = 23
#VT_UINT_PTR = 38
#VT_R4 = 4
#VT_R8 = 5
#VT_CY = 6
#VT_DATE = 7
#VT_BSTR = 8
#VT_DISPATCH = 9
#VT_ERROR = 10
#VT_VARIANT = 12
#VT_UNKNOWN = 13
#VT_DECIMAL = 14
#VT_VOID = 24
#VT_HRESULT = 25
#VT_PTR = 26
#VT_SAFEARRAY = 27
#VT_CARRAY = 28
#VT_USERDEFINED = 29
#VT_LPSTR = 30
#VT_LPWSTR = 31
#VT_RECORD = 36
#VT_FILETIME = 64
#VT_BLOB = 65
#VT_STREAM = 66
#VT_STORAGE = 67
#VT_STREAMED_OBJECT = 68
#VT_STORED_OBJECT = 69
#VT_BLOB_OBJECT = 70
#VT_CF = 71
#VT_CLSID = 72
#VT_VERSIONED_STREAM = 73
#VT_BSTR_BLOB = $fff
#VT_VECTOR = $1000
#VT_ARRAY = $2000
#VT_BYREF = $4000
#VT_RESERVED = $8000
#VT_ILLEGAL = $ffff
#VT_ILLEGALMASKED = $fff
#VT_TYPEMASK = $fff
;-Start of test code
Procedure StringToBStr (string$) ; By Zapman Inspired by Fr34k
Protected Unicode$ = Space(Len(string$)* 2 + 2) ;reserve twice as much bytes for Unicode (note:the +2 is not needed here and can safely be removed, see explanation above)
Protected bstr_string.l
PokeS(@Unicode$, string$, -1, #PB_Unicode) ;convert string to unicode
bstr_string = SysAllocString_(@Unicode$) ;allocate space for the bstr's length+characters+null and copy string there (returns pointer to characters)
ProcedureReturn bstr_string
EndProcedure
ImportC ""
sprintf_.i(lpOutput.s, lpFormat.s, *arglist.p-bstr) As "_sprintf"
EndImport
Declare DoSomeStuff(x.IXnumbers)
Declare.d BstrToFloat(*v.VARIANT)
CoInitialize_(#Null)
Xnumbers.IXnumbers
OpenConsole()
; try to create object, if fails - try to register and recreate
If CoCreateInstance_(CLSID_Xnumbers, 0, 1, IID_Xnumbers, @Xnumbers)
PrintN("failed to create Complex class, registering...")
;use the following line if you put the xNumbers dll in same folder as this application
; RunProgram("regsvr32.exe", "/s "+#DQUOTE$+ GetPathPart(ProgramFilename())+"Xnumbers.dll"+#DQUOTE$,"")
;use the following line if you put the xNumbers dll in C:\WINDOWS\system32 folder
RunProgram("regsvr32.exe", "/s "+#DQUOTE$+ "C:\WINDOWS\system32\Xnumbers.dll"+#DQUOTE$,"")
WaitProgram(regsvr32)
If CoCreateInstance_(CLSID_Xnumbers, 0, 1, IID_Xnumbers, @Xnumbers)
PrintN("failed to register Xnumbers")
Else
Goto __ok__
EndIf
Else
__ok__:
DoSomeStuff(Xnumbers)
Xnumbers\Release()
EndIf
CoUninitialize_()
Input()
CloseConsole()
Procedure DoSomeStuff(x.IXnumbers)
;set_interface x,IXnumbers
result.VARIANT
result1.VARIANT
result2.VARIANT
double1.VARIANT
double1\vt = #VT_R8 ;/*DOUBLE*/
double2.VARIANT
double2\vt = #VT_R8 ;/*DOUBLE*/
precision.VARIANT
precision\vt = #VT_I4 ;/*INT Or custom*/
precision\intVal = 42 ;/*precision*/
;setprecision precision.intVal
Integer.VARIANT
Integer\vt =#VT_I4 ;/*INT*/
base.VARIANT
base\vt =#VT_I4 ;/*INT*/
vNull.VARIANT
vNull\vt =#VT_EMPTY
mystring.s
formula.i
; after calling methos the type of result is BSTR (unicode string)
; check it: result.vt = VT_BSTR
; -------------------------------------------------------------
; display string:
; _printf("%S\n", result.bstrVal) - print unicode string (console only)
; VariantClear(result) - must free string
; -------------------------------------------------------------
; or copy it to your string
; STRING mystring - for precision>255 use
; - ISTRING[precision+1] mystring
; _sprintf(mystring, "%S", result.bstrVal)
; VariantClear(result) - must free string
; print mystring
; -------------------------------------------------------------
; or convert to FLOAT:
; myfloat = BstrToFloat(result) - string is freed
; -------------------------------------------------------------
; or convert to INT/UINT:
; myint = BstrToInt(result) - string is freed
; myuint = BstrToUint(result) - string is freed
; -------------------------------------------------------------
; PI
x\xPi(precision, result)
;print "Pi: ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN("Pi: "+mystring)
; 2PI
x\x2Pi(precision, result)
;print "2Pi: ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "2Pi: "+mystring)
; PI/2
x\xPi2(precision, result)
;print "PI/2: ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "PI/2: "+mystring)
; log(100) [10]
Integer\intVal = 2
base\intVal = 10
x\xLog(Integer, base, precision, result)
;print "log(2): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "log(2): "+mystring)
; xExpBase(a:VARIANT, x:VARIANT, opt DgtMax:VARIANT, result:VARIANT)
Integer\intVal = 10
base\intVal = 10
x\xExpBase(Integer, result, precision, result2)
;print "10^log(2): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result2\bstrVal)
PrintN( "10^log(2): "+mystring)
; sin(1)
Integer\intVal = 1
base\intVal = 10
x\xSin(Integer, precision, result2)
;print "sin(1): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result2\bstrVal)
PrintN( "sin(1): "+mystring)
; Asin()
x\xAsin(result2, precision, result)
;print "sin(): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "Asin(Sin(1)): "+mystring)
; sin(90)
double1\dblVal = 90*0.0174532925199433 ;ToRadians(90.0)
x\xSin(double1, precision, result) ;/*yyy why Not 1.0000*/
;print "sin(90): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "sin(90) (double): "+mystring)
; cos(45)
double1\dblVal = 45*0.0174532925199433 ;ToRadians(45.0)
x\xCos(double1, precision, result)
;print "cos(45): ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "cos(45) (double): "+mystring)
; 15376.44178 * 4.1
double1\dblVal = 15376.44178
double2\dblVal = 4.1
x\xMult(double1, double2, precision, result)
;print "15376.44178 * 4.1 = ", BstrToFloat(result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN( "15376.44178 * 4.1 (double)= "+mystring)
;-
formula = StringToBStr ("1/(1+x*x)")
;there seems to a bug in xNumbers, x And angle seem To point To same placeholder
; precision\intVal = 22
result1\vt = #VT_R8
result1\dblVal = 0.5 ;using double may result in loss of precision
; x
x\xEval(@formula, result1, precision, result2, result)
mystring = Space(1024) ; 1024 is the maximum size
sprintf_(mystring, "%S", result\bstrVal)
PrintN("xEval = "+mystring)
SysFreeString_(formula) ; free memory
; PrintN( StrD(BstrToFloat(result)))
VariantClear_(result) ; free BSTR string
VariantClear_(result1) ; free BSTR string
VariantClear_(result2) ; free BSTR string
ProcedureReturn
EndProcedure
;-End of test code
Procedure.d BstrToFloat(*v.VARIANT)
s.s
If (*v\vt<>#VT_BSTR)
MessageRequester ("", "VARIANT type is Not BSTR: .vt="+Str(*v\vt), 0)
ProcedureReturn 0
EndIf
s = Space(255)
sprintf_(s, "%S", *v\bstrVal)
VariantClear_(*v)
ProcedureReturn ValD(s)
EndProcedure