Think of something that you wish Authorware could do but it doesn't? Let the our good friends at Macromedia know via the wishlist. Please let us know if you find any of the materials on this site inappropriate or offensive. Please include the url and why the material should be reviewed. Comments and questions about the site are also welcome. Please no Authorware questions, use the AWARE list. |
Back
11013 - How DLL's work in AWARE and why you get GPF's when you do something wrong. by - Bruce van Horn "Hope that somebody out there can give me some clue's to understand
better what is going on when using DLL-functions with AuthorWare. Suppose there
are two functions in a DLL. The first one is supposed to return a handle. So
I defined returnvalue WORD when loading the DLL-function and initializing this
value in AW to be 0. Using a displayicon to display it's value, indeed there
is a value shown. The second function is using the handle from the first function
as an argument and returning a boolean. When loading this function I use SHORT
for the returnvalue and WORD again for the argument. Now something goes wrong.
When executing this second function I get an error (showing that KERNEL32 has
problems with it) and AW hangs. On the pages 611-616 of 'Using Authorware' there's
a lot about DLL's, but I don't understand it. As far as I understand something
is going wrong when AW get's the returnvalue from the first function to pass
it to the second function because AW is changing it's type to a 'signed long
integer' or a 'double-precision-floating-point' or a 'zero-terminated string'
Anybody to shine a little light on this? I could help you more if you told me what functions you are trying to use.
However let me do a general explanation of how DLL's work in AWARE and why you
get GPF's when you do something wrong. DLL's are just libraries of functions. A function is a piece of procedural
code that carries out an operation and returns a value based on that operation.
For example if I invoke a function in my dog called GetSlippers, it goes and
gets me slippers, then returns them to me (so the return value is 2). This differs
from a subroutine or a procedure which simply carries out an operation and returns
nothing. Functions in AWARE can be internal or external and there really is no difference
between them. Internal functions are housed in a library just like a DLL-its
called the AWARE run time. AWARE is set up with a built in interface to access
those functions without you having to do anything other than call them in your
program. External functions are written in some other language. Macromedia has designed
the DLL interface around the C/C++ (well, actually its closer in many respects
to Pascal) programming conventions. This is handy since many functions most
people want to use are found in the Windows API--a large collection of functions
callable from any program. The API is written for C/C++ programmers, so there
is a sort of standard to follow. When using external functions in Authorware you need several peices of information: 1) The exact name of the function Variable types are the key to success. Just think of them as boxes in different
sizes and shapes--and therefore specific to the information they can contain. A string must contain certain information that is different than a number.
For example, if you tell the system that the value 65 is an integer, it will
treat it as '65'. If you tell the system its a string, it will process it as
the letter 'A'. Different variable type--different kind of information. Bearing that in mind, the operating system will give you a container in
memory to hold the information you specify. But if you specify the wrong kind
of variable, the contents don't fit the container and the contents then spill
over into areas that might consist of other containers. When this happens you
get an error, usually a General Protection Fault. Your function has tried to
write to memory it does not own. In other words, the content you tried to put
in the variable is the wrong shape and size. Sometimes functions don't really need to return anything, or they don't
really need an argument. In that case, they can take literally 'nothing' as
an argument. This is not the same as taking 0--its called VOID. In some other cases, a DLL manipulates memory directly by using addresses.
This is just like addresses in a city--except they are a bit more obtuse. When
the program or DLL wants to manipulate memory, it creates what's called a pointer
so it can easily reference that address. Strings are an example of this. A string
is just a series of characters, or an array or characters if you will. If I
want to process the word ""Hello"", the computer sees I've
set it up as a string, so it creates a container in memory to hold it and then
it creates a pointer so it can find it again. ""Hello""
is a five letter word, but how does the computer know that? We could tell it
to only process the first five characters of this string, but we need a better
way. Computers delimit a string with a null character. A null is nothing. Its
not zero! Its literally a character representation of nothing (great philosophical
problem here!). So the computer reads the string until it reaches the null character,
then it knows its done. This is known as a null terminated string. Okay, that covers strings and whole number, but what about decimals and
fractions? These numbers are represented as floating point numbers. You have
probably seen these if you ever took a science class and dealt with scientific
notation. Something like 1.456348 X 10 to the 4th power. This would give you
a handy decimal notation method that the computer can handle. I'll leave it
at that since this post is already way too long. The level of precision merely
tells you how fractional you can get in the same manner that a short integer
has a smaller range of numbers than a long integer does. Now for your specific problem. You've got function 1 that needs a handle.
Handles are almost always 16 bit unsigned integers. An unsigned integer can
have a value ranging roughly from 0 to 65,000. By contrast, a signed integer
can range from roughly -32,000 to +32,000. So programmers have to determine
if their value will ever be negative when deciding which value to use. Handles
are unsigned. The windows term for an unsigned integer is a word. That part
works fine from what you've said. Function 2 takes the handle from the first as an argument and returns a
boolean. A boolean can have only 2 values--true (1) or false (0). Is there any
sign inherent here? No, the value is never less than 0--so a signed value is
not needed. This is certainly not your fault--you coded it as short, and that's
what the book says. Here's the trick. According to the windows api reference,
a boolean value is actually 16 bit--outside the range of a short since its signed.
So even though the value is either true or false, Windows treats the value as
a 16 bit number. It's sort of like saying comparing a gallon of water to a drop
of water. The water is identical in each case, but the container size is different.
Change your value to WORD and you should be OK. Check your values when they come back on your boolean. I'll bet the number
being passed back doesn't fall within the SHORT limits (+/-32,768)." Add your review Back |