The
only problem with using VB to get to the F4 variables (and it's not a big
one in my opinion), is that VB cannot access the shared memory variables
directly. They have to be copied into a data type that VB can access.
Data Type Variable
This is where we create the 'container' that will house
out F4 variables. This code should also be placed into 'Declarations'
section of your program.
Public Type FlightData
x As Single
y As Single
z As Single
xDot As Single
yDot As Single
zDot As Single
alpha As Single
beta As Single
gamma As Single
pitch As Single
roll As Single
yaw As Single
mach As Single
kias As Single
vt As Single
gs As Single
windOffset As Single
nozzlePos As Single
internalFuel As Single
externalFuel As Single
fuelFlow As Single
rpm As Single
ftit As Single
gearPos As Single
speedBrake As Single
epuFuel As Single
oilPressure As Single
lightBits As Integer
End Type
Global F As FlightData
The above code defines a user variable called FlightData,
that houses all the F4 variables. The final statement Makes the entire
variable available as 'F.' If you wanted to view the F4 rpm variable,
you would refer to it as F.rpm
Memory Mapping
VB does not directly support access to memory mapped files.
To access these files, we will use a few WIN32API functions. The
functions we will use are:
OpenFileMapping Opens the memory
map for reading, returns a 'handle'
MapViewOfFile Maps a 'view'
of the file, or the start of the address space
UnmapViewOfFile UnMaps the view
when we're finished
CloseHandle Closes the
file map and releases the handle
To use the above functions, you must first declare them
in the 'Declarations' section of your VB code. The syntax of the
declare statements are (these must appear all on a single line each):
Declare Function OpenFileMapping
Lib "kernel32" Alias "OpenFileMappingA" (ByVal dwDesiredAccess As Long,
ByVal bInheritHandle As Long, ByVal lpName As String) As Long
Declare Function MapViewOfFile
Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess
As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long,
ByVal dwNumberOfBytesToMap As Long) As Long
Declare Function UnmapViewOfFile
Lib "kernel32" (lpBaseAddress As Any) As Long
Declare Function CloseHandle
Lib "kernel32" (ByVal hObject As Long) As Long
As I mentioned in the beginning, in order to access the
variables, we have to copy them to a data type that VB will access.
Fortunately we can copy the memory to a data 'type' variable through the
use of another WIN32API function. This function is called CopyMemory,
and as with the above functions, must be declared in the 'Declarations'
section of your program. The syntax for the declare statement is:
Declare Sub CopyMemory Lib "kernel32"
Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal
numbytes As Long)
How does it all work?
In this section, I'm going to use actual VB code, that
is HEAVILY commented. This code could be cut and pasted directly
into a VB program, and should run as is! Please keep in mind that
this is meant as a tutorial that demonstrates how to access Falcon data
from VB. A 'useful' program requires a little bit more creativity.
Please see my F4Server.ZIP file on the simpits ftp server for a fully implemented
program (source code included).
Start of the program
The first thing we want to do is get a 'handle'
to the shared memory area.
SharedMemHandle = OpenFileMapping(FILE_MAP_READ,
True, "FalconSharedMemoryArea")
If Falcon is running, and we've done everything
else properly, we should have a valid
handle called 'SharedMemHandle'. Next
we'll test to see if this is true.
If SharedMemHandle Then
If
we have a valid SharedMemHandle, then let's map a view of the file.
This actually
give
us a pointer to the start of the memory location for the F4 variables.
This
pointer
is called 'SharedMemPointer'.
SharedMemPointer
= MapViewOfFile(SharedMemHandle, FILE_MAP_READ, 0, 0, 0)
Else
If we
didn't get a valid SharedMemHandle, then Falcon isn't running, or there
is
a bug
in our code.
Msgbox
( "Error: Invalid Handle - Falcon is not running")
Let's
clean up our mess and shut down. Since we never got a valid handle,
we
were never able to map a view of the file. Just to be nice, we'll
release
the
handle we tried to use.
CloseHandle
(SharedMemHandle)
End
End If
At this point, we have a valid handle, that we used to
get a valid pointer!
Now lets move the data into our 'type' variable.
This is done
with the copymemory function
CopyMemory F, ByVal SharedMemPointer,
Len(F)
All the variables are now available! Please keep
in mind that they
are only as current as the last time you executed the
CopyMemory
function. To keep them current, you must re-execute
the CopyMemory
function.
If we had a form with a textbox on it, this code would
display our rpms
Form1.TextBox1.Text = F.rpm
If we had a form with a textbox on it, this code would
display our indicated airspeed
Form1.TextBox2.Text = F.kias
To close everything down, and exit gracefully, we should
first unmap our view
of the file
UnmapViewOfFile (SharedMemPointer)
Then we release our handle
CloseHandle (SharedMemHandle)
That's all
END
|