| **Navigation:**  [[welcome to my product .htm|User's Guide and Tutorials]] > Advanced Topics >====== Development and Deployment Strategies ====== | [[advanced topics.htm|{{btn_prev_n.gif|Previous page}}]][[welcome to my product .htm|{{btn_home_n.gif|Return to chapter overview}}]][[development and deployment strategies.htm#mpd|{{btn_next_n.gif|Next page}}]] | | || [[development and deployment strategies.htm#mpd|Multi-Programmer Development]] [[development and deployment strategies.htm#one-piece exe|One-Piece EXEs]] [[development and deployment strategies.htm#exe plus dlls|EXE Plus DLLs]] **Overview'EXEs, .LIBs, and .DLLs** The way you organize your application files can have a significant impact on the efficiency of your work processes throughout the life cycle of the application. For example, developing all of your procedures within a single .APP file keeps everything under one roof. This can be a benefit for smaller applications'keeping all files in a single directory makes finding and backing up the files quite easy if there are reasonably few files. This benefit can become a problem for larger applications'backing up or compiling hundreds of files at once can be time consuming and tricky. So you can see how organization affects the development phase of your application. The ultimate size and number of your application's executable files affects your ability to quickly and easily distribute upgrades and bug fixes to your end users. This is one way that organization affects the maintenance phase of your application. This appendix discusses of some of the factors you should consider when deciding how to structure your application files, both for the development and maintenance phases of the application. This includes instructions on how to implement the organization that best suits your needs. **Generally speaking, the ****//benefits//**** of breaking large programming projects into smaller logically related pieces are:** __**Development Phase**__ ·Smaller, more manageable problems. ·The ability to test and debug smaller pieces of code. The smaller the code, the easier it is to isolate problems. ·Faster compile and link times. ·The ability to make your code generic and reusable. ·The ability to delegate programming tasks to multiple programmers. __**Maintenance Phase**__ ·The ability to sell and distribute discrete application components. ·The ability to deploy bug fixes and upgrades with small files. ·For reused code, the ability to affect many procedures by changing a single source file. **These benefits are most easily realized by creating multiple .APP files that are used to make separate .DLLs or .EXEs that are developed and tested independently. As the project nears completion the executable files are linked together and tested as a whole.** {{blk2blue.jpg|blk2blue.jpg}} Some //problems// associated with breaking large programming projects into smaller pieces include: __**Development Phase**__ ·Managing more files: backing up, naming conventions, and synchronization of files becomes a bigger job. ·Correctly linking together related pieces of executable code. __**Maintenance Phase**__ ·Managing more files: version control is more difficult. The end user must have a complete set of compatible files. ·For reused code, unintentionally affecting many procedures by changing a single source file. ·Accidentally omitting a required file during deployment. **Multi-Programmer Development** Clarion's modular approach to source code management, its procedure-oriented language, and its ability to produce .DLL and .LIB files allows your team to split the work on big programming projects. Our recommended methods for group development assume the team is linked by a LAN, which supports the ability to grant read-only or read-write privileges to individual developers. It doesn't matter whether the LAN is peer-to-peer or a more traditional network operating system. We also assume the project will have a Team Leader or Project Manager to coordinate the overall efforts of the team. Finally we assume, as per our license agreement, each Clarion programmer has a licensed copy of Clarion. The first step to prepare for a team-development project is to create a data dictionary available to all developers, but which only the team leader may edit. An Application Generator option (**Open Dictionary Files and Template Registry as Read-Only** check box under **Tools** {{blttria.jpg|BLTTRIA.jpg}} **Application Options**) provides support for opening the Data Dictionary and TemplateRegistry.TRF in read only mode, so that many developers working with separate .APP files can work with the same dictionary. Prior to beginning the project, all team members should synchronize their //TemplateRegistry.TRF// and their template source files. The Team Leader should be responsible for the dictionary and the template set. Once the data dictionary is created, there are three basic approaches your team can take to use Clarion as a group development tool: ·Procedure-oriented: The team divides the application into procedures, as listed in the Application Tree. These should be organized around the various windows, dialog boxes, menu items, and command buttons that form the user interface. The Team Leader prepares a "shell .APP," (or master) upon which all the others build. Each team member receives a copy of the .APP file, then works on a procedure (or procedures). The Team Leader imports the completed procedures into the master .APP file for compiling. This approach is suitable for small to medium size projects. ·Module-oriented: The team divides the application into its target-file-level components (.DLL's, .LIB's, and executables). Each team member creates a single target file. Separate project files (.PRJ) compile the individual components. A master project file may include all the other project files, building all target files at once. This approach is suitable for medium to large size projects. ·Sub-Application: The team divides the application into its target-file-level components (.DLL's). Each team member creates a single application or Dynamic Link library (.DLL). A master application calls each .DLL. This approach is suitable for medium to large size projects. This method provides the most flexibility and minimizes version control concerns. __**Enabling and Organizing Team Projects**__ This section describes how to set up the Clarion Development Environment at each workstation, and where to store the files necessary for all three group development approaches: 1.Create the data dictionary in a shared directory. All team members working on the project must have read rights to the directory. Those permitted to edit the dictionary should also have write privileges, though it may be best that only the Team Leader be allowed to edit it. 2.Create a shared directory for resource files. Provide read rights for all team members to icon, cursor, bitmap, and other resource files. 3.Within Clarion, at each workstation, choose **Tools** {{blttria.jpg|BLTTRIA.jpg}} **Application Options**. This opens the //Application Options// dialog. 4.Check the **Open Dictionary Files and Template Registry as Read-Only **checkbox. This specifies that when working in the Application Generator, the copy of Clarion residing at each workstation opens the dictionary file on the network in read-only mode. The purpose is to ensure that no one accidentally deletes a field, file, or key needed by other team members. For this reason, we recommend that only the Team Leader have write privileges to the directory containing the dictionary. To modify the dictionary, all team members must close all applications that use the dictionary. The Team Leader must clear the Open Dictionary Files and Template Registry as Read-Only box in order to modify the dictionary and, upon completion, check the box again. 5.Press the **OK** button to close the dialog. 6.Create a directory on each workstation's local drive to hold each team member's individual .APP and source files. The real work is planning how to split the development project, which is what the remainder of this chapter discusses. {{notebox.jpg|NoteBox.jpg}} If your application's .DLLs use your application files, the FILE definitions and all Global variables must be declared in a .DLL (not the .EXE) and exported. See the [[development and deployment strategies.htm#sub-application approach|Sub-Application Approach]] for more information. __**Procedure Oriented Approach**__ The Application Generator lets you import and export procedures from other .APP files. With careful management, a Team Leader can organize development so that each team member can compile and test a copy of the application that includes the parts he or she works on. Each views the entire menu and the application's most important dialog boxes, yet executes only the procedures for which that team member is responsible. {{notebox.jpg|NoteBox.jpg}} This approach is only necessary If your team members are not using Enterprise Edition, or do not have Version Control/team Developer. To accomplish this, each team member requires a //copy// of a "master" .APP file, containing the MAIN procedure (which would most likely be an Application Frame procedure), plus other procedures inserted below it as "ToDo" procedures. Each team member then "plugs in" the procedures he or she is responsible for. To assemble the complete application, using the **Application** {{blttria.jpg|BLTTRIA.jpg}} **Import from Application** command, the Team Leader imports each finished procedure into the master .APP file. **The following outlines a possible implementation of the procedure-oriented approach:** 1.Create the data dictionary and set up the workstations as described above. 2.Create a "master" .APP file in a directory to which only the Team Leader has write privileges. 3.Within the .APP file, edit the MAIN procedure's most important user interface elements and declare its global variables. The user interface elements may include any dialog boxes or windows of particular importance to the application. As you specify procedure calls to menu items and/or toolbar controls, the Application Generator automatically adds "ToDo" procedures the application tree. 4.Save and copy the .APP file to each team member's local drive. If the team prefers, you can rename each copy; for example, MASTER01.APP, MASTER02.APP, etc. or JIM.APP, JANE.APP, etc. 5.Team members work on the procedures for which they are responsible, using their own copy of the .APP file. With the .APP file containing the complete user interface, each team member can compile an interim build locally, to test their own procedures while under development. 6.Each team member synchronizes their local directory with an equivalent directory on the network at the end of each work session, or copies renamed .APP files to a "master" directory. 7.To update the master .APP file with the latest work from a developer, the Team Leader replaces a "To Do" procedure in the Application Tree with a completed procedure in a team member's .APP by importing it. The Team Leader chooses **Application **{{blttria.jpg|BLTTRIA.jpg}}** Import from Application**, indicating the same procedure in the .APP file in the developer's network directory. Any sub-procedures added by the team members will be brought along as new "To Do" procedures. When the Team Member completes these, they can be imported in the same manner. As the Team Leader's master .APP file "grows", it can be copied back to team members' individual directories (but only if all the work done by the individual team member was imported). This way, each team member has access to all the work completed by other members of the team. Keep in mind that each of the other member's modules will need to be compiled on the member's local drive. If the Team Leader is also a team member'i.e., also responsible for coding procedures'it's best to maintain a completely separate directory and copy of the master .APP file for that work. 8.After importing the updated procedure, the Team Leader checks to see if it added any new "To Do" procedures to the tree, and imports those, if ready. Communication at this step is vital. In fact, based on E-Mail messages within the team, the Team Leader could optionally import "works in progress." 9.The Team Leader compiles the project, so that it now includes each team member's work added through importing procedures. 10.The Team leader repeats the last three steps on a periodic basis until all work by all team members is complete, and the entire application can be tested. __**Module Oriented Approach**__ With this approach, each team member creates a separate target file. This requires splitting the application into a "Main" executable and "secondary" executables or dynamic link libraries. The individual team members maintain separate project files (.PRJ) for each component. The Team Leader creates a master project file to build all target files at once. The key to successfully implementing this strategy is extensively pre-planning the "division of labor" between the various target files created by the application. The **Notes** section below provides a few helpful suggestions. The following outlines a possible implementation of this strategy: 1.Create the data dictionary and set up the workstations as described above. 2.Each team member creates their own .APP and .PRJ files, specifying the dictionary file on the network as the data dictionary, and a directory on the local drive as the default directory for the .APP file. Each team member specifies a different target file. One particular .APP or .PRJ file creates the executable which launches or calls library functions or procedures in the others. To the end user, this is the .EXE program to start when working with the complete application. 3.Each team member synchronizes their local directory with an equivalent on the network at the end of each day. 4.The Team Leader creates a master .PRJ file which includes all the other .PRJ files, in a network subdirectory. The Team Leader inserts the name of each .PRJ file (previously copied to the network) in the Projects to Include item in the Project Tree. 5.The Team Leader compiles the master project, which in turn compiles all the target files one by one. 6.The Team leader repeats the last step on a periodic basis until all work by all developers is complete, and the entire application can be tested. __**Notes on Splitting the Project**__ There are probably as many ways to split a project, as there are projects; this section provides a few general suggestions. ·If a task associated with a menu command requires extensive coding, store it in its own external .DLL, so that only a single developer can work on it. A typical example might be an accounting program, which could store all procedures and functions associated with accounts receivable in one .DLL file, accounts payable in another, and so forth. ·Organize .DLL's by function; for example, place utility procedures and functions such as backups and file exports in a UTILITIES.DLL. ·Store user defined functions in .LIB files; distribute the compiled .LIB files to each team member as they become available so that each may test any functions required in their own work. __**Notes on File Management**__ Each multi-developer project has its distinct properties, so you'll undoubtedly adapt the following suggestions to fit your needs: ·Create a subdirectory for each team member on the network drive, either at the same level or below the one holding the data dictionary file. Give each developer write privileges only to their own directory, and use a network utility to synchronize the directories at the end of the day. This not only serves as a backup, but provides the Team Leader access to the latest work done by all members of the team. ·If the application under development creates an .INI file, a copy of it should reside in a network directory to which all team members have write privileges, so that if anyone should need to add a variable to the file, other members of the team can see it. __**Sub-Application Approach**__ This section describes the steps to create a program using one main application and several sub-applications compiled and linked as external .DLLs. Dividing a large project into multiple .DLLs provides many benefits: ·Each sub-application can be modified and tested independently. ·Developers can work on their portion of the project without interfering with others on the development team. ·Each sub-application can be compiled as a .DLL and tested in the main program without recompiling the entire project. This reduces compile and link time. ·Dynamic Pool Limits are avoided in large projects. ·Future updates can be deployed by shipping a new .DLL, reducing shipping costs. {{tipbox.jpg|TipBox.jpg}} The Clarion runtime libraries assume the .EXE or .DLL where a window was most recently opened is where any referenced icons are located. With this approach, each Team Member creates a separate .DLL that is called by a "master" application. This requires splitting the application into a "Main" executable and "secondary" .DLLs. The individual team members maintain separate application files for each component. The Team Leader creates a master application that calls the sub-applications and a "data" application that contains (and exports) all the File definitions and Global variables. Optionally, members can call procedures from another member's .DLL. This method also requires extensive pre-planning of the "division of labor" between the various target files created by the application. The previous section provides a few helpful suggestions. The following outlines a possible implementation of this strategy: 1.Create the data dictionary and set up the workstations as described above. 2.Create a "data" application to store and export all data declarations. All Global variables or structures and all file definitions are defined (and exported) in this application. Use the following settings: In the //Application Properties// dialog: | **Dictionary File:** | master dictionary | | **First Procedure:** | none | | **Destination Type:** | .DLL | In the //Global Properties// dialog **General** tab: **Generate template globals and ABCs as External**:     OFF In the //Global Properties// dialog **File Control **tab: | **Generate All File declarations**: | ON | | **External**: | NONE EXTERNAL | | **Export All File declarations**: | ON | {{notebox.jpg|NoteBox.jpg}} You do not need (and should not have) OWNER, NAME or PASSWORD on those FILES which have the EXTERNAL attribute. These attributes should only be on FILEs not declared EXTERNAL. 3.Team member create their own sub-application .APP files, specifying the dictionary file on the network as the data dictionary, and a directory on the local drive as the default directory for the .APP file. Each team member specifies a different target file using the following settings: In the Application's Module Tree: Choose **Application **{{blttria.jpg|BLTTRIA.jpg}}** Insert Module**, then in the //Select Module Type// dialog, select **ExternalDLL**, then in the //Module Properties// dialog, select the corresponding .LIB for the .DLL containing the data definitions. In the //Application Properties// dialog: | **Dictionary File:** | master dictionary | | **Destination Type:** | .EXE for development | | | .DLL for release | {{notebox.jpg|NoteBox.jpg}} **Changing the Destination Type enables procedures to be exported. Make sure that every procedure that is called by the master application or another .DLL has the Export Procedure check box in the Procedure Properties checked (the check box is only available after changing the destination type).** ** ** In the //Global Properties// dialog **General** tab: **Generate template globals and ABCs as External**:     ON In the //Global Properties// dialog **File Control** tab: | **Generate All File declarations**: | OFF | | **External**: | ALL EXTERNAL | | **All Files declared in another .App**: | ON | | **Declaring Module**: | (Leave this blank) | In the //Global Properties// dialog **External Module Options** tab: **Standard ABC LIB/DLL?**     ON One particular .APP creates the executable which launches or calls library functions or procedures in the others. To the end user, this is the .EXE program to start when working with the complete application. 4.Team members synchronize their local directory with an equivalent on the network at the end of each day. 5.Team Members release their compiled and linked .DLLs to the Team Leader. Each sub-application has a "dummy" frame (not exported) that calls the sub-application's procedures so the Team Member can test the sub-application by compiling it as an .EXE. Once it passes testing, the member compiles it to a .DLL by changing the Application Properties' Destination Type to .DLL and releases the file to the Team Leader. {{tipbox.jpg|TipBox.jpg}} If you edit the Redirection file to include "." at the start of the *.DLL and *.LIB search paths, Clarion generates the *.DLL and *.LIB files into the local sub-application subdirectory instead of \Clarion\BIN and \Clarion\OBJ. This is a little safety precaution that prevents the *.DLL and *.LIB from getting into other Team Members' hands before it's ready. In addition, adding the Master directory to the end of these search paths enables the sub-application or main application to find the completed .LIB's and .DLL's belonging to other sub-applications in the master subdirectory. 6.The Team Leader copies the released .DLLs into the master directory and creates a master .APP file which calls the entry point procedures in the .DLLs. The Master .APP is typically just a bare bones application with just a splash screen and a main frame with a menu and toolbar. The .DLLs are called at run-time so you don't need to compile a large Master .EXE. The Master .APP should have the same settings as the sub-applications except that it is always compiled as an .EXE. The master .APP should have these settings: In the //Application Properties// dialog: | **Dictionary File**: | master dictionary. | | **Destination Type**: | Executable (.EXE) | In the //Global Properties// dialog **General** tab: **Generate template globals and ABCs as External**:     ON In the //Global Properties// dialog **File Control** tab: | **Generate All File declarations**: | OFF | | **External**: | ALL EXTERNAL | | **All Files declared in another .App**: | ON | | **Declaring Module**: | (Leave this blank) | In the Application's Module Tree: Choose **Application **{{blttria.jpg|BLTTRIA.jpg}}** Insert Module**, then in the //Select Module Type// dialog, select **ExternalDLL**, then in the //Module Properties// dialog, select the corresponding .LIB for the .DLL containing the data definitions. Choose **Application **{{blttria.jpg|BLTTRIA.jpg}}** Insert Module**, then in the //Select Module Type// dialog, select **ExternalDLL**, then in the //Module Properties// dialog, select the corresponding .LIB for the sub-application .DLL. Repeat this step for each sub-application. For each procedure the main application calls, edit the ToDo procedure as follows: | **Template**: | External template. | | **Module name**: | Select the .LIB from the drop-down list. | **If necessary delete any empty generated modules.** 7.The Team Leader compiles the master .APP and tests the calls to the .DLLs. 8.The Team leader repeats the last step on a periodic basis until all work by all developers is complete, and the entire application can be tested. {{blk2blue.jpg|blk2blue.jpg}} **One-Piece EXEs** A one-piece .EXE is an .EXE file that contains everything it needs to run except files that cannot be linked in (.VBXs, data files, etc.). That is, the .EXE needs no associated .DLLs, .ICOs, etc., because they are already linked into the .EXE. __**When to Use One-Piece EXEs**__ __**Development Pros and Cons**__ Potentially none, because the final state of the .EXE does not necessarily affect the organization of the project at development time. For example, an application may be developed using several .APP files to generate separate executables (.EXE or .LIB). Eventually the separate executables are linked together to make a one-piece .EXE. The make time for the one-piece .EXE is greater than the make time for its individual components, so at the point in the development cycle where you link in and test all components, make times increase. __**Maintenance Pros**__ **You deploy a single file. There's no chance of forgetting a required executable file or of deploying an incompatible set of .EXEs and .DLLs. There's no chance of a conflict with a different version of a .DLL with the same name.** __**Maintenance Cons**__ Your changes require relinking the entire project, plus deploying a larger file. Larger files are generally more difficult to deploy. Your end user cannot share .DLLs between multiple programs; that is, if two or more one-piece .EXEs execute the same code, that code is duplicated within each .EXE'an inefficient use of disk space. __**Conclusion**__ Use a one-piece .EXE for small and medium applications that are infrequently deployed. That is, the application is reasonably stable or the application is distributed to only a few end users. Use .LIBs when you want to separate your development process into multiple applications, but you want to deploy your application as a one-piece .EXE. You can initially make each application an .EXE so it can be independently developed and tested. When you are ready to integrate all the applications together, make the called applications into .LIBs, then link them into the parent application. __**How to Implement One-Piece EXEs**__ Create a one-piece .EXE from one or several .APP files. The simplest approach is to create an .EXE from a single .APP file. Alternatively, you may use several .APP files to create one or more .LIBs which are linked into the one-piece .EXE. {{tipbox.jpg|TipBox.jpg}} You may want to create .EXEs rather than .LIBs during the development cycle in order to reduce link times and to permit isolated testing and debugging of discrete executables. Near project completion, convert to .LIBs by changing the Project's Target Type or the Application's Destination Type to LIB. To create a one-piece .EXE from one or more .APP files: __**Set the Parent Application's Destination Type to EXE**__ The highest level (parent) application's **Destination Type** should be set to .EXE in the //Application Properties// dialog. The parent application is the one whose procedures are not called by any other application's procedures. 1.Open the parent application. 2.Select the **Properties** tab from the Application Tree. 3.In the //Application Properties// dialog, choose executable (.EXE) from the **Destination Type** drop-down list. {{tipbox.jpg|TipBox.jpg}} Setting the Project's Target Type is equivalent to setting the Application's Destination Type and vice versa. __**Set the Parent Application's Link Mode to LIB**__ Set the parent application's **Link Mode** to **Lib** in the Project Editor's //Application// dialog. This links the Clarion runtime functions, including all referenced file drivers into the application's .EXE. 1.Open the parent application. 2.Choose **Project **{{blttria.jpg|BLTTRIA.jpg}}** Project Options** from the menu. 3.In the //Application// tab, choose **Lib** from the **Link Mode** drop-down list. {{notebox.jpg|NoteBox.jpg}} Run-Time Library in this context automatically includes all file drivers used by your application! If there are no LIBs, then you are ready to make your one-piece EXE. Skip to the last step in this section Make and Run Your One-Piece EXE. __**Make the LIBs**__ You may make LIBs for other purposes than creating one-piece .EXEs. The following information, except //Set the LIB Application's Run-Time Library to Local//, applies for any LIBs you make. Make and test your LIB application just as you would any other application. Note the name of your LIB and it's procedures because you will reference these names in your parent application. When you are finished testing, remake your LIB application with the following settings to create a LIB file to link into the parent EXE. 1.Select the **Properties** tab from the Application Tree. 2.Choose //Library(.LIB)// from the **Destination Type** drop-down list then press **OK**. __**Declare the LIB's Procedures Globally**__ By default, the ABC Templates declare procedures locally using local MAPs. Local MAPs minimize compile times but are inappropriate when making a LIB and will produce a "Link Error: //procedure//@F is unresolved..." when making the calling application. Within the LIB's application, you should declare globally, each procedure called by the parent application. So either 1.In the //Procedure Properties// dialog, check the **Declare Globally** box for each called procedure; or 1.Choose **Tools **{{blttria.jpg|BLTTRIA.jpg}}** Application Options** from the menu, select the **Generation** tab, then clear the **Create Local Maps** box to declare all procedures globally. __**Set the LIB Application's Link Mode to Lib**__ Set the LIB application's **Link Mode** to //Lib// in the Project Editor's //Global Options// dialog. This tells the linker that the Clarion run-time functions, including all referenced file drivers, are in the parent application's EXE. 1.Choose **Project **{{blttria.jpg|BLTTRIA.jpg}}** Project Options** from the IDE menu. 2.In the //Application// tab, choose //Lib// from the **Link Mode** drop-down list. 3.Choose **Build **{{blttria.jpg|BLTTRIA.jpg}}** Build Solution** from the menu to make the .LIB. __**Add the LIB Modules to Your Parent Application**__ The following steps tell your parent application that some external procedures are called from a particular .LIB. 1.Open the parent application. 2.Choose **Application **{{blttria.jpg|BLTTRIA.jpg}}** Insert Module** from the menu. 3.In the //Select Module Type// dialog, choose **ExternalLIB**. 4.In the //Module Properties// dialog **Name** field, type the name of the .LIB then press **OK**. 5.In the //Module Properties// dialog **Map Include File** field, type the name of the include file that contains the called procedures' prototypes. You must create this file. You can do so by copying the procedure prototypes from the generated appname.clw file and saving them into a separate .inc file. __**Add the External Procedures to Your Parent Application**__ 1.Open the parent application. 2.Press the **New Procedure **button from the //Application Tree//. 3.In the //New Procedure// dialog, type the name of the external procedure and press **OK**. 4.In the //Select Procedure Type// dialog, select **External**. This opens the //Procedure Properties// dialog. The **Files**, **Procedures**, **Formulas**, and **Extensions** buttons on this dialog are not meaningful for external procedures and you should ignore them. 5.In the **Module Name** drop-down list, select the .LIB that contains the external procedure then press **OK**. This tells the parent application where to find the external procedure. __**Make and Run Your One-Piece EXE**__ 1. Open the parent application. 2. Choose **Debug **{{blttria.jpg|BLTTRIA.jpg}}** Make and Run All** from the menu. The Application Generator and the Project System generate source code, then compile and link the one-piece EXE based on: ·Application Properties' Executable(.EXE) Destination Type ·Project Editor'Global Options .EXE Target Type ·Project Editor'Global Options Local Run-Time Library ·The .LIB Modules and external procedures you inserted into your application tree. **EXE Plus DLLs** **.EXE Plus .DLLs is an .EXE that requires some associated files that could have been linked into the .EXE at compile time. That is, the .EXE does need associated .DLLs, .ICOs, etc., because they are not already linked into the .EXE.** The use of this configuration primarily affects the maintenance cycle of the application; however, the creation of one or more .DLLs implies the presence of multiple .APP files, which also affects the development cycle. The .DLLs often include the Clarion run-time .DLL and one or more file driver .DLLs. Please be aware that these .DLLs may be hidden by creating a one-piece .EXE, or by linking them into another .DLL that you create! See [[development and deployment strategies.htm#hiding the clarion run-time library|Hiding the Clarion Run-time Library]]. {{tipbox.jpg|TipBox.jpg}} The Clarion runtime libraries assume the .EXE or .DLL where a window was most recently opened is where any referenced icons are located. __**When to Implement**__ **Use an .EXE plus .DLLs for two or more applications that share a common .DLL. This saves disk space. A good example of this is two Clarion applications that use the same TopSpeed file driver: ****//ClaTPS.DLL//****. The applications and shared .DLLs should be fairly stable so you don't have two different .DLLs with the same name on the same machine. Different .DLLs with the same name can lead to confusion and worse if the .DLL files are not managed properly.** Use an .EXE plus .DLLs for very large applications or for applications that are deployed frequently. This lets you deploy only the portions of the application that actually change. __**How to Implement**__ To create an .EXE plus .DLLs: __**Set the Parent Application's Destination Type to EXE**__ Set the parent application's **Destination Type** to .EXE in the //Application Properties// dialog. {{notebox.jpg|NoteBox.jpg}} Typically, an .EXE calls .DLLs, however, a.DLL may call other .DLLs. 1.Open the parent application. 2.Select the **Properties** tab from the Application Tree. 3.In the //Application Properties// dialog, choose **Executable(.EXE)** from the **Destination Type** drop-down list. {{tipbox.jpg|TipBox.jpg}} Setting the Project's **Output Type** is equivalent to setting the Application's **Destination Type** and vice versa. __**Set the Parent Application's Link Mode to Dll**__ The parent application's **Link Mode** should be set to //DLL// in the Project Properties dialog. This allows the .EXE to link in Clarion external functions at run-time from ClaRUN.DLL. 1.Open the parent application. 2.Choose **Project **{{blttria.jpg|BLTTRIA.jpg}}** Project Options** from the menu. 3.In the //Application// tab, choose //Dll// from the **Link Mode** drop-down list. If you are not making your own .DLLs, that is, if there is only one .APP file, then you are ready to make your .EXE plus .DLLs. Skip to the last step in this section, [[development and deployment strategies.htm#make and run your .exe plus .dlls|Make and Run Your .EXE Plus .DLLs]]. __**Generate Global Data and ABCs EXTERNAL**__ {{notebox.jpg|NoteBox.jpg}} If your application's .DLLs use your application files, the FILE definitions and all Global variables must be declared in a .DLL (not the .EXE) and exported. Generate the parent application's global data and ABC Library declarations with the EXTERNAL attribute. This allows the ABC Library objects, the GlobalRequest and GlobalResponse variables, plus global variables you define to be shared between local and external functions. Open the parent application. 1.Choose the **Properties** tab from the Application Tree, and press the **Actions** button. 2.In the //Global Properties// dialog, check the **Generate template globals and ABCs as EXTERNAL** box. 3.Exit the Global Properties and open the Data / Tables Pad (F12). 4.In the //Global Data// dialog, press the **Change** button. 5.In the //Field Properties// dialog, select the **Attributes** tab. 6.In the **Storage Class** group, check the **EXTERNAL-**and** DLL **check boxes. 7.**Repeat 5 through 7 for each global data item.** __**Make the DLLs**__ Make and test your .DLL application just as you would any other application. Note the name of your .DLL and it's procedures because you will reference these names in your parent application. Typically one of the .DLLs (the "Data DLL") contains file declarations and ABC Library objects only, with no other procedures. We recommend this configuration because it is easy to set up and to maintain. If needed (your system uses more than one data dictionary), you can make a separate DLL for each data dictionary, and a separate DLL for the ABC Library objects. When you are finished testing, remake each DLL application with the following settings to create a DLL file to link into the parent EXE at runtime. 1.Choose the **Properties** tab from the Application Tree. 2.Choose **Dynamic Link library(.DLL)** from the **Destination Type** drop-down list. Choosing a Destination Type of .DLL automatically exports (makes public) each procedure in the application. {{tipbox.jpg|TipBox.jpg}} To optimize performance, export only the procedures called by another executable. 3.In the //Procedure Properties// dialog, clear the **Export Procedure** box for each procedure not called externally. Procedures that are only called within the .DLL application need not be exported. __**Set the DLL Application's Link Mode to DLL**__ Set the .DLL application's **Link Mode** to **DLL** in the Project Properties //Application// dialog. This lets the .DLL link in Clarion functions at run-time from ClaRUN.DLL. 1.Choose **Project** {{blttria.jpg|BLTTRIA.jpg}} **Project Options** from the menu. 2.In the //Application// tab, choose //Dll// from the **Link Mode** drop-down list. 3.Choose **Build** {{blttria.jpg|BLTTRIA.jpg}} **Build Solution** from the menu. __**Add the DLL modules to the Parent Application**__ The following steps tell your parent application that some external procedures are called from a particular .DLL. 1.Open the parent application. 2.Choose **Application **{{blttria.jpg|BLTTRIA.jpg}}** Insert Module** from the menu. 3.**In the ****//Select Module Type//**** dialog, choose ****ExternalDLL****.** {{notebox.jpg|NoteBox.jpg}} When you make a .DLL with Clarion, you also generate a corresponding stub .LIB. The linker links the stub .LIB at compile time so your application can call the .DLL at run-time. 4.In the //Module Properties// dialog, press the **Module Name** ellipsis button to select the stub LIB (or type the LIB name) that corresponds to the .DLL, then press **OK**. __**Add the External Procedures to the Parent Application**__ 1.Open the parent application. 2.Press the **New** **Procedure **button. 3.In the //New Procedure// dialog, type the name of the external procedure then press **OK**. 4.In the //Select Procedure Type// dialog, select **External**. This opens the //Procedure Properties// dialog. The **Files**, **Procedures**, **Formulas**, and **Extensions** buttons on this dialog are not meaningful for external procedures and you should ignore them. 5.In the **Module Name** drop-down list, press the **Module Name** ellipsis button to select the stub LIB (or type the LIB name) that corresponds to the .DLL, then press **OK**. __**Make and Run Your EXE Plus DLLs**__ 1.Open the parent application. 2.Choose **Debug **{{blttria.jpg|BLTTRIA.jpg}}** Make and Run All** from the menu. The Application Generator and the Project System generate source code, then compile and link the .EXE plus .DLLs based on: ·Application Properties' Executable(.EXE) Destination Type ·Project Editor'Global Options .EXE Target Type ·Project Editor'Global Options Standalone Run-Time Library ·The .DLL Modules and external procedures you inserted into your application tree. __**Hiding the Clarion Run-time Library**__ Making a one-piece .EXE hides the Clarion run-time Library within the .EXE. You can also hide the run-time Library by linking it into another .DLL as follows: __**Set the Parent Application's Destination Type to .EXE**__ The parent application's **Destination Type** should be set to **Executable(.EXE)** in the //Application Properties// dialog. The parent application is the one whose procedures are not called by any other application's procedures. 1.Open the parent application. 2.Select the **Properties** tab from the Application Tree. 3.In the //Application Properties// dialog, choose **Executable(.EXE)** from the **Destination Type** drop-down list. {{tipbox.jpg|TipBox.jpg}} Setting the Project's **Output Type** is equivalent to setting the Application's **Destination Type** and vice versa. __**Set the Parent Application's Link Mode Library to CustomDLL**__ The parent application's **Link Mode** should be set to **CustomDLL** in the Project's //Application// dialog. This tells the .EXE to link in Clarion external functions at run-time from a .DLL other than ClaRUN.DLL. 1.Open the parent application. 2.Choose **Project **{{blttria.jpg|BLTTRIA.jpg}}** Project Options** from the menu. 3.In the //Application// tab, choose //CustomDll// from the **Link Mode** drop-down list. {{notebox.jpg|NoteBox.jpg}} **Link Mode in this context automatically includes all file drivers used by your application!** If your application's .DLLs use your application files, the FILE definitions and all Global variables must be declared in a .DLL (not the .EXE) and exported. __**Generate Global Data and ABCs EXTERNAL**__ Generate the parent application's global data as EXTERNAL. This allows the GlobalRequest and GlobalResponse variables, plus global variables you define to be shared between local and external functions. 1.Choose the **Properties** tab from the Application Tree, and press the **Actions** button. 2.In the //Global Properties// dialog, check the **Generate template globals and ABCs as EXTERNAL** box. 3.Exit the Global Properties and open the Data / Tables Pad (F12). 4.In the //Global Data// dialog, press the **Change** button. 5.In the //Field Properties// dialog, select the **Attributes** tab. 6.In the **Storage Class** group, check the **EXTERNAL-**and** DLL **check boxes. Repeat 5 through 7 for each global data item. __**Make the DLL Containing Clarion's Run-time Functions**__ 1.Choose **File **{{blttria.jpg|BLTTRIA.jpg}}** New** {{blttria.jpg|BLTTRIA.jpg}}** Solution, Project or Application **from the menu. 2.In the New Project dialog, select the //Clarion for Windows// category and the Application Quick Start. 3.In the **Name** field, type the name of the application. 4.Press the **Create** button. 5.The //Application Properties// dialog appears. 6.If applicable, select a data dictionary. 7.Choose **Dynamic Link Library(.DLL)** from the **Destination Type** drop-down list and press **OK**. __**Set the DLL Application's Link Mode to LIB**__ 1.Choose **Project** {{blttria.jpg|BLTTRIA.jpg}} **Project Options** from the menu. 2.In the //Application// tab, choose LIB from the **Link Mode** drop-down list. 3.Choose **Build** {{blttria.jpg|BLTTRIA.jpg}} **Build Solution** from the menu. This links the Clarion functions into your .DLL at compile time so that they can eventually be linked into your .EXE at run-time. It also generates a Module Definition file (.EXP) for your .DLL. You edit the .EXP file in the following step to export the run-time functions from your .DLL. __**Export the Clarion Run-time Functions**__ 1.Open the parent application. 2.Choose **Build **{{blttria.jpg|BLTTRIA.jpg}}** Build Solution** from the menu. Because the run-time functions have not been exported, the linker generates an "unresolved" error for each function. Expect several hundred to one thousand plus error messages, depending on your application. In the following steps we use the Clarion Text Editor to convert the error messages into EXPORT statements. You may use any text editor for this purpose. 3.DOUBLE-CLICK in the **Errors** Pad to open the Text Editor. 4.**Delete all messages except the "...function is unresolved..." messages.** 5.Choose **Search **{{blttria.jpg|BLTTRIA.jpg}}** Replace** from the menu. 6.In the **Find what** field, type is //unresolved in file <;filename.ext>//. Replace //<;filename.ext>// with the filename and extension in the first message. 7.In the **Replace with** field, type an ampersand and a question mark with no spaces, like this: @?. 8.Press the **Replace All** button. This converts the error messages for file <;filename.ext> into EXPORT statements. Repeat steps **5** through **8** until all the ...function is unresolved... messages are converted. 9.Delete any duplicate statements. Select all the statements and copy them to the clipboard, then paste them into a word processor or spreadsheet that has sort capabilities. Sort the statements so that duplicate statements appear together, then delete the duplicates. Select all the remaining statements, copy them to the clipboard and save your work. 10.Insert the EXPORT statements into the export file (.EXP) for the .DLL application in the following steps. 11.If you have not already done so, choose **Save and Close** from the menu to exit the Text Editor. 12.Choose **File **{{blttria.jpg|BLTTRIA.jpg}}** Open** from the menu. 13.In the **File Name** field, type //*.exp//, then press ENTER. 14.Select the .EXP file associated with your .DLL (not your parent application), then press **OK**. This opens the .EXP file with the Text Editor. 15.Scroll to the end of the file then click the mouse to set the insertion point. 16.Choose **Edit **{{blttria.jpg|BLTTRIA.jpg}}** Paste** from the menu. {{tipbox.jpg|TipBox.jpg}} You can modify the .EXP file by embedding text in .EXP related Global Embed points. __**Make the DLL Application with the Exported Functions**__ 1.Open the .DLL application. 2.Choose **Build **{{blttria.jpg|BLTTRIA.jpg}}** Build Solution** from the menu. This links the Clarion run-time functions into your .DLL and exports them so they can be called at run-time by your .EXE. __**Make the Parent Application**__ 1. Open the parent application. 2. Choose **Project **{{blttria.jpg|BLTTRIA.jpg}}** Make and Run All** from the menu. Now that the Clarion run-time functions are exported, the linker resolves calls to those functions and issues no more unresolved messages. __**Making LIBs and DLLs for Other Environments**__ Unlike most non-Clarion development tools (Delphi, PowerBuilder, Visual C++, Visual Basic, etc.), Clarion generates executables that use register based parameters. Since Clarion uses register based parameters and these other tools do not, when making DLLs for other tools, you must prototype your exported Clarion procedures with the C or PASCAL attribute, depending on the calling environment. See //C and PASCAL calling conventions// in the core help for more information. Non-Clarion environments generally cannot link Clarion created LIBs because of memory model incompatibility. However, they can link the stub LIBs associated with Clarion DLLs.