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


Article appears courtesy of Danny Engelman’s Gems and Jewels of the AWARE list

"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
2) The type of variable or variables the function expects to receive (if any) 3) The type of variable for the return value (if any)

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)."

There are 0 reviews
Add your review
Back