Brew™SDK entry (2)

Source: Internet
Author: User

Part 2-Run "Hello brew" on the simulator"

Before following this article to learn relevant knowledge, you need the following environment:

1. Microsoft Visual C ++ 6.0 (or later)

2. Brew SDK of Version 1.1.

To learn the minimum requirements of the system and obtain more detailed information, see the README file of SDK 1.1 for SDK installation instructions. Note: Here I suppose you have read an article earlier in this series, "What is brew", and the previous article "Part 1-prerequisites" in this series ". I further assume that you have created a module information file (hellobrew. and a brewx applet resource file (hellobrew. and copy them to "... yourbrewdir/examples/MIF/256 color/"and"... yourbrewdir/examples/en/256 color/"directory. At the same time, the yourbrewdir/examples/hellobrew/"directory must use the hellobrew_res.h file generated by the brew resource editor, and use the application source file created by the brew Application Wizard (hellobrew. c ). If you want to learn more, read the first part or the documents attached to the SDK.

In this routine, you need to know the file name is very important. In particular, the application directory and module information file (. MIF) must have the same name (that is, the same prefix) as the target. dll file ). Note: you can define the name of The. dll file by opening the link option card in the Project Settings dialog box (select project menu> settings. If you follow the first part, you should have a file named correctly in the corresponding directory.

Finally, let me remind you that in this article, the words "applet" and "application" will be used in turn, representing the same thing.

Set Visual C ++

In the first part, all required project settings are managed by the brew Application Wizard. However, we still need to provide an executable file to run the. dll file in the debugging phase, and ensure that brew can find the. dll file of the application. For the first request, the path must be provided for brew_emulator.exe.

To meet the second requirement, we need to make sure that the linked program uses hellobrew. DLL is written in the project root directory (... /hellobrew/) instead of the default DEBUG directory (... /hellobrew/debug /). Because the simulator automatically searches for hellobrew. dll in the directory named hellobrew.
 
Understand source code
First, let's take a rough look at the source code generated by the Application Wizard in the hellobrew project. If you have not done so, use visual c ++ to open the hellobrew project, select FileView, and expand the source Files folder. You can see three source code files: aeeappgen. C, aeemodgen. C, and hellobrew. C. The first two files enable our application to be bound to the BREW application execution environment (aee ). Aeemodgen. c management module. Each module basically contains more than one small program (applets) that is mutually dependent on each other ). When an end user activates an application, the aee creates a module that calls the aeeclscreateinstance () function required by each application and instantiates the application in sequence.

This allows us to understand why applets and applications can be used in a loose way. Why? Because a applet can be understood as a container, it holds all the files that only allow the features created by developers to interact with aee and run on the device. For example, such a container can provide interfaces for Shell services and for device monitors. In this way, we can think that an application is a small program and any created functions can be developed. In fact, if we use the C ++ principle in this example to explain that hellobrew (a function created by a developer) must inherit from the aeeapplet structure of brew in public mode, from this perspective, an application is a small program (the relationship between Is ). Aeeappgen. C provides the aeeapplet_new () function. hellobrew will call this function to set the aeeapplet part of the hellobrew application. We will discuss aeeclscreateinstance () and aeeapplet_new () in more detail soon ().

Now we have a basic concept for how to combine these parts. Now let's take a look at the Framework Code generated by the brew Application Wizard. As for the included header files, you may have guessed that aeemodgen. Contains the aeemodgen. c statement, and aeeappgen. H also declares aeeappgen. C. Aeeshell. H provides the Shell Interface API declaration. If you want to learn more about this important interface, you can find ishell In the brew api reference that comes with the brew SDK. We will not conduct in-depth research here, and add our own code to hellobrew. C.

Now, let's skip the definition of hellobrew_handleevent () to see aeeclasscreateinstance () (or aeeclscreateinstance (), Translator's note ). This function is the place where hellobrew is exposed to aee. When aee sends a launch request to the application, aeemodcreateinstance () defined in aeemodgen. c calls the aeeclasscreateinstance () function of Applet type. Because brew is single-threaded, only one small program is activated at a time no matter how many small programs exist in a module. By calling the ishell_startapplet (), one applet can be started by another applet. In this case, the current applet is suspended and calls aeeclasscreateinstance () with the class ID provided by ishell_startapplet (). Obviously, aeeclasscreateinstance () requires the logical branch of each class ID in the module. There is only one small program in our module, so aeeclasscreateinstance () only needs to process one class ID.

In the previous article, we remember that a class ID of hellobrew is generated in the hellobrew. MIF file. The MIF editor creates a hellobrew. Bid file. Use # define to define this class ID as aeeclsid_hellobrew. Obviously, this module obtains the class ID from the module information file (hellobrew. MIF) and passes it as the first parameter to aeeclscreateinstance ().

The second parameter, pishell, is an ishell pointer provided by aee when the module is loaded for the first time. When aeeapplet_new () is called, The m_pishell Member of the aeeapplet structure must be set to pishell. This ishell pointer provides hellobrew access to all the APIs of the ishell interface.

The third parameter, Po, is a pointer to the hellobrew module. This parameter will initialize the m_pimodule parameter of the aeeapplet structure when aeeapplet_new () is called. Our code does not involve this pointer. The aeeappletrelease () function defined in aeeappgen. C requires the pointer to release the Dynamic Allocation Module when hellobrew is finished.

Finally, ppobj is a pointer to a common pointer. Here we use a void type **, because * ppobj can point to two things. Fortunately, we only need objects of the iapplet type. If you are a little unfamiliar with pointer usage, you must use double indirect addressing to ensure that when aeeapplet_new () returns * ppobj points to a valid iapplet object. If ppobj is simply defined as void * ppobj (that is, a single Indirect addressing), ppobj will not change when aeeapplet_new () is returned. The parameter transfer mechanism in C language will only pass a simple copy of The ppobj pointer to aeeapplet_new () without changing the original value in aeeclscreateinstance. Because we want aeeapplet_new () to modify the same pointer referenced in aeeclscreateinstance (), we can only pass the value parameter instead of the form parameter.

The second to last parameter passed to the aeeapplet_new () function is a pointer to the event handle of our application. Once aee receives an event to hellobrew, it will call this function. If the last parameter is not null, we need to pass a pointer to a function that releases the dynamically allocated data when the application ends. This pfnfreeappdata is a function pointer. This function receives parameters of the iapplet * type and returns void. For demonstration, we will add such a function in hellobrew.

Let's look at the code of the hellobrew_handleevent () framework. The first parameter points to the iapplet instance. In this function, Pi will be used to access m_pishell and m_pidisplay data members of the applet. When we add our own code to hellobrew, we will discuss this in more detail.

The second parameter, ecode, is the same as its name. It refers to the Event code used to discover what actions lead to a call to hellobrew_handleevent. The last two parameters include event-type data. In the header file aee. H, you can find a complete and detailed list of events, as well as descriptions of the data provided by the event parameters wparam and dwparam. In the brew SDK user guide, you can find more user-friendly event lists, including different key event and key code, and descriptions of wparam and dwparam event types.

Add source code
Now let's add our own code in hellobrew. You can see a simple version of "hello" in helloworld. c Under "... yourbrewdir/examples/helloworld ". To prevent duplication and make our example more interesting, we will create our own applet data structure, provide initappdata () and freeappdata () functions, from the resource file (hellobrew. bar refer to the first preparation) Load strings and use the istatic controller of brew to display them.

We need to add aeestdlib. H to the include header file list. This header file includes malloc () and free (), as well as the Helper function mentioned in the brew api reference.

Then, our application needs to be able to access the class ID in hellobrew. Bid and the string ID in hellobrew_re1_h.

Note: An application cannot contain any static (global) data. Therefore, our application data structure is defined as a global data structure (struct, at least C program ). We also asked aeeclscreateinstance () to manage the instances in the heap. This brings another important note: the stack space on the device is very limited. For example, Kyocera qcp3035e has only 500 bytes of available stack space. Obviously, you need to use the stack as few as possible. To achieve this goal, you can minimize the number of function calls and minimize the number of non-atomic elements) the local variable is allocated to the heap. When the data to be transferred is greater than four digits, the pointer is used.

The application data structure provides a container for loading everything that programmers need to maintain throughout the application lifecycle. This includes the application's aeeapplet section, where you can access shell, display, and maintain module pointers. Aeeapplet must be the first member of the data structure, which is mandatory. Another member of this data structure is a pointer to the istatic controller that is used to display the defined string.

First and foremost, we modified the first parameter passed in aeeappletnew. In addition to the space required by the aeeapplet of hellobrew, we also need to use aeeapplet_new () to allocate space for the istatic * of the applet data structure. To achieve this, we pass sizeof (hb_app) to aeeapplet_new () as the first parameter, instead of the original sizeof (aeeapplet ).

Step 2: to add a freeappdata () function to hellobrew, we need to pass a pointer (hb_freeappdata () to aeeapplet_new () as the last parameter. This function will be registered into aee and automatically called upon application termination. Figure 9 shows the definition of hb_freeappdata. As you can see, the basic task of this function is to call istatic_release () to release the istatic controller.

The final change of aeeclscreateinstance () is to call hb_initappdata (). Here, the istatic * member in our applet data structure is initialized to null.


The initial code generated by the brew Application Wizard is greatly modified in hellobrewhandleevent. At the top, we define a pointer to the data structure of our applet, and assign the first parameter of this function, iapplet * To this pointer. In the entire event handle, this pointer is used to access the m_pishell member of aeeapplet in hellobrew. In addition, it also provides access to the m_pistat pointer that we use to represent the istatic controller.

At the beginning of evt_app_start, the first local variable we define is the aeedeviceinfo type variable. This structure includes member variables that save the device screen size and color depth. For more details about data members, refer to the final data structure (data type, Translator's note) Section of brew API. I remember reminding you to minimize the use of stack space. We should allocate memory for this structure on the heap and define pointers locally to monitor it. This applet does not need to worry about the danger of stack space depletion. For simplicity, I define this structure as a local variable.

Next, we will see a simple rectangle object (aeerect), which is used to determine the size and location of the static controller, and determine several caches to save the title and text of m_pistat respectively. Aechar is the type definition of uint16 (typedef) (refer to aee. h), while uint16 is the type definition of unsigned short INTEGER (refer to aeecomdef. h ). In this way, aechar can be used to store Unicode or become a wide characters type variable. In this way, wbufttl and wbuftxt point to an empty string consisting of Characters in the wide character set. Refer to the helper function section in the brew api reference to learn about tools for manipulating wide character set strings.

After verifying the validity of m_pishell, we can call it to assign a value to Di. Next, the screen size members Di. cxscreen and Di. cyscreen are used to set the positions and sizes of rectangular objects with static controllers. In the screen coordinate system, the origin is the upper left corner of the display. when we move to the right, the X coordinate increases. When we move down, the Y coordinate increases.

When you call ishell_createinstance (), specify aeeclsid_static as the class ID of the Request interface. If the call is successful, m_pistat will point to a valid istatic. The class ID of other interfaces can be found in aeeclassids. h. After creating an istatic, we call istatic_setrect () to set its rectangle and pass the pointer to the previously initialized rectangle structure to it.

After allocating memory for the previously defined buffer (wbufttl, wbuftxt), we call ishell_loadresstring () twice: The title of istatic and the text. The two buffers submit the title and text to istatic_settext (). Istatic_setproperties () is used to define the title and text location, and call istatic_redraw () to display the static controller on the screen. Refer to the istatic chapter in the brew api reference to learn more about the call methods of these functions.

Note that brew cannot tolerate memory leaks. Therefore, you must be sure that all calls to malloc () correspond to calls to free (), while calls to ishell_createinstance () corresponding to the I * _ release () call. The two buffers used are released (free () at the bottom of evt_app_start ). Hellobrew releases an istatic instance when calling istatic_release () in hb_freeappdata.

The remainder of hellobrewhandleevent. Here we have added an evt_key event to apply the "CLR" button standard on the mobile phone. When the "CLR" button is pressed, false is returned to notify aee to close the application. The preset "CLR" button on the phone means "back to the next level". Your application should implement this action.

Because the m_pistat release is handled by hb_freeappdata (), we do not need to do anything in the evt_app_stop event handle.

Run hellobrew

Start the brew simulator (emulator). You can click the shortcut in the brew SDK Program Group or the red exclamation mark in Visual C ++ to start the simulator.

Click the shortcut in the brew SDK program group, or click the red exclamation point in Visual C ++ to start the brew simulator. Use the left and right arrow keys to locate hellobrew In the BREW application manager. After the selection, you can see the 85 × 40 big image we made in the middle of the simulator screen. Press enter on the keyboard to display the second frame of the image on the simulator display.

Since I have defined another MIF directory for hellobrew. MIF, the first frame displayed in your simulator may not be as shown in 10. I am doing this to avoid finding the hellobrew icon in the icons of the self-contained instance applications in a large number of sdks. That is to say, the simulator only displays applications with valid. MIF files in the currently specified MIF directory. You can set the generated hellobrew. if you want to move the value of MIF, for example, ".. yourbrewdir/examples/yourmif/256 color/", and then set it to the initial MIF directory in the tool menu of the simulator. For detailed settings, see the brew MIF editor guide.

Simulator debugging
If you follow the instructions in the beginning of this article to set the Visual C ++ section, you can use the Visual C ++ debugger as usual. For example, to make sure that aeeclscreateinstance () works as expected, you can place the cursor in this function and click "Run To curor" in the debug toolbar ". Then you can run this function in a single step, set the value of some variables to be monitored, jump into another function, or place the cursor in another function or event handle and click "Run To curor" again ". If you are not familiar with the visual C ++ debugger, read the relevant chapters in the Visual C ++ documentation.

If the simulator cannot display the sharp z800 phone interface at startup, you can use File> load device... to replace the simulated device. In ".. yourbrewdir/devices/", select the z800 phone device file, end with qsc, and click open to load the device.

Note that the simulators in the SDK combine more rigorous heap checks, which will help you find possible errors during early development, such as memory overflow and array out-of-bounds. The 2.0 simulator can be used together with the 1.x SDK. For more information about how to install sdks of multiple versions on one machine, see sdk2.0 Installation Guide.

Copyright 2002, Golden Creek Software Inc.
By Murray Bonner

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.