Im Artikel "
VB mit PowerBASIC erweitern" wurde gezeigt, warum es manchmal
wünschenswert und manchmal sogar unumgänglich ist, die "schützende Hülle" von VB zu verlassen und
eigene Programme mit DLLs zu erweitern, die in einer systemnäheren Sprache geschrieben sind. Es wurde
beschrieben, wie dies in
PowerBASIC bewerkstelligt
werden kann.
Auch wenn PowerBASIC sehr effizient und äusserst preiswert ist, handelt es sich doch um Closed-Source-Software,
und damit haben wir VB.Classic-Entwickler ja nun nicht gerade die besten Erfahrungen gemacht. Interessant
wäre daher, ob es Open-Source-Alternativen gibt, die für unseren Einsatzzweck in Frage kommen.
Gibt es, und zwar ebenfalls als BASIC-Dialekt. Das Projekt nennt sich
FreeBASIC. Der Compiler hat 2014 das Beta-Stadium hinter sich gelassen und ist sehr leistungsfähig und
zuverlässig. Der folgende Code zeigt, dass alles, was wir im. o.g. Artikel mit PowerBASIC umgesetzt
haben, auch mit FreeBASIC möglich ist.
FreeBASIC-Code:
#include once "windows.bi"
#include once "win/ole2.bi"
EXTERN "windows-ms"
FUNCTION AddOne (BYVAL l AS INTEGER) AS INTEGER EXPORT
RETURN l + 1
END FUNCTION
SUB AddOneInPlace(BYREF l AS INTEGER) EXPORT
l += 1
END SUB
FUNCTION UpperCase _
(BYVAL arg AS ZSTRING PTR) AS BSTR EXPORT
CharUpperBuff arg, len(*arg)
RETURN SysAllocStringByteLen(arg, LEN(*arg))
END FUNCTION
FUNCTION IsZero(BYVAL l AS INTEGER) AS SHORT EXPORT
IF l = 0 THEN
FUNCTION = -1
ELSE
FUNCTION = 0
END IF
END FUNCTION
SUB SwapLongs (BYREF l1 AS INTEGER, BYREF l2 AS INTEGER) EXPORT
SWAP l1, l2
END SUB
SUB SwapStrings (BYVAL s1 AS ZSTRING PTR, BYVAL s2 AS ZSTRING PTR) EXPORT
SWAP *s1, *s2
END SUB
FUNCTION SystemDirectory() AS BSTR EXPORT
DIM AS UINTEGER l
DIM b AS BYTE PTR
DIM r AS BSTR
l = GetSystemDirectory(BYVAL 0&, 0)
b = ALLOCATE(l)
l = GetSystemDirectory(b, l)
r = SysAllocStringByteLen(b, l)
DEALLOCATE b
RETURN r
END FUNCTION
FUNCTION ShiftRight(BYVAL l AS INTEGER, BYVAL offs AS INTEGER) AS INTEGER EXPORT
l SHR = offs
RETURN l
END FUNCTION
FUNCTION GetInstalledRamSize() AS INTEGER EXPORT
DIM AS HMODULE hModule
hModule = DYLIBLOAD("KERNEL32.DLL")
IF hModule THEN
DIM pGlobalMemoryStatusEx AS FUNCTION(BYREF lpBuffer AS MEMORYSTATUSEX) AS INTEGER
pGlobalMemoryStatusEx = DYLIBSYMBOL(hModule, "GlobalMemoryStatusEx")
IF pGlobalMemoryStatusEx THEN
DIM mInfoEx AS MEMORYSTATUSEX
mInfoEx.dwLength = SIZEOF(mInfoEx)
IF pGlobalMemoryStatusEx(mInfoEx) THEN
FUNCTION = mInfoEx.ullTotalPhys SHR 10
DYLIBFREE hModule
EXIT FUNCTION
END IF
END IF
DYLIBFREE hModule
END IF
SCOPE
DIM mInfo AS MEMORYSTATUS
mInfo.dwLength = SIZEOF(mInfo)
GlobalMemoryStatus VARPTR(mInfo)
FUNCTION = mInfo.dwTotalPhys SHR 10
END SCOPE
END FUNCTION
END EXTERN
Und hier der VB-Code:
Option Explicit
Declare Function AddOne Lib "fbtest1.dll" (ByVal l As Long) As Long
Declare Sub AddOneInPlace Lib "fbtest1.dll" (ByRef l As Long)
Declare Function UpperCase Lib "fbtest1.dll" (ByVal s As String) As String
Declare Function IsZero Lib "fbtest1.dll" (ByVal l As Long) As Boolean
Declare Sub SwapLongs Lib "fbtest1.dll" (ByRef l1 As Long, ByRef l2 As Long)
Declare Sub SwapStrings Lib "fbtest1.dll" (ByRef s1 As String, ByRef s2 As String)
Declare Function SystemDirectory Lib "fbtest1.dll" () As String
Declare Function GetInstalledRamSize Lib "fbtest1.dll" () As Long
Declare Function ShiftRight Lib "fbtest1.dll" (ByVal zahl As Long, ByVal offset As Long) As Long
Sub Main()
Dim l1 As Long, l2 As Long
Dim s1 As String, s2 As String
l1 = AddOne(41)
Debug.Assert l1 = 42
AddOneInPlace l1
Debug.Assert l1 = 43
s1 = UpperCase("hällo wörld")
Debug.Assert s1 = "HÄLLO WÖRLD"
Debug.Assert IsZero(l2) = True
l2 = 55
Debug.Assert IsZero(l2) = False
SwapLongs l1, l2
Debug.Assert l1 = 55
Debug.Assert l2 = 43
s2 = CStr(l1)
SwapStrings s1, s2
Debug.Assert s1 = "55"
Debug.Assert s2 = "HÄLLO WÖRLD"
Debug.Assert ShiftRight(16, 1) = 8
Debug.Print "Systemverzeichnis: " & SystemDirectory()
Debug.Print "Installierter Hauptspeicher: " & GetInstalledRamSize() & " KB"
End Sub
Test bestanden! ;-)
Der vom Compiler erzeugte Code ist echter Maschinencode und von keinerlei Laufzeitkomponenten abhängig.
Auch hier der Hinweis: Mit FreeBASIC verlassen wir in vielerlei Hinsicht die "schützende Hülle"
von VB; Sie sollten ihren FB-Code daher besonders ausführlich testen.