![]() |
|
Published 1997-07-01 Printer-friendly version
In this column over the months we will explore the various ways in which the Clarion environment promotes code reuse. Apart from the obvious way of using templates, a route far too few developers take advantage of, there are also the more traditional methods of function, and class, libraries.
The benefits of reusing code are obvious. For every application you do you can reuse the generic functions that you created for the one before. This saves time, improves the features in your program, and generally makes for more cost-effective programming. As your libraries grow it becomes easier and easier to lay the framework for more sophisticated applications, without any effort at all. Most third party products employ this philosophy, but in this column well explore how you can take advantage of these features. And before you ask, no, you dont need to be a Clarion expert either.
In this first article I will walk through the steps youll need to do in order to create your own function library. You can use this library as the basis of your own libraries. In later articles well delve into the various forms your library can take, and well even remove some of the mysticism from the template language and get you going writing your own templates.
There are different types of functions, and ideally, for convenience, you should separate the different types of functions into separate libraries. For example a library like Secwin contains only security-related functions. ezHelp contains only help related functions etc. In this article were going to create a general-purpose library. You can use this as the basis of as many libraries as you like. In my own personal library I include all those simple functions that just dont seem to fit in anywhere else.
The first big decision to make is if a library should be stored as an APP file, or as a project. Both have their advantages, but in essence an APP file should be used for functions containing screens and/or files, and a project should be used for the rest, which are essentially hand coded functions.
The advantage of projects is that excess code is kept to an absolute minimum. However if the function uses a data file or screen then dont mess around, go straight to an APP. By using an APP you can take advantage of existing templates which certainly simplify things. If the size of the library isnt critical (and these days very few are) then you can even include source code functions in an App.
The second big decision to make is to document what youre doing. Now like you Im not a big fan of writing documentation, but one thing Ive learnt is that if you dont document your function, youll never reuse it. I cannot emphasize enough the importance of this step. And dont let it bog you down either - it doesnt need to be a big deal. All you need to document is the function name, what parameters it takes, what it returns and in a nutshell what it does.
Ok, well were ready to start. In this issue Im going to base my library on an APP file. Next month well explore the methods and advantages of making a Project function library.
Firstly make an empty directory and in it create a new APP file. Im going to call mine CS (as in CapeSoft). I recommend using 3 or fewer letters, the reason for which well discuss later. Avoid the names of existing Clarion, or third party DLLs, for example RUN, CLA, DOS, TPS etc. Dont select any dictionary for the app. Select the "Destination Type" as "DLL". Well talk later about maintaining multiple versions of the same library, but for now let's make it a 16-bit DLL.
Now youve got your empty application which proclaims a lonely ToDo called Main. Before continuing click on Main and make it into a Source template. Click its "Export this function" switch off. Were never going to use this Main function, but we also dont want to export it.
Let's go ahead and add our first function. Im going to add a function called Calendar, which predictable brings up a calendar on the screen and allows the user to select a date. It in turn uses 2 other functions called DaysInMonth and DayOfTheWeek. These functions might come in handy one day in their own right so well export them as well.
As an aside, Ive lifted this function from my own function library and one of the interesting things here is that although it uses a window I used the Source template to write it and not the Window template. This makes it harder to maintain but it does keep the code really small and tight. I have to say that if I rewrote the function today Id go ahead and use the Window template. When in doubt always go with the approach thats easiest to maintain and change. The size of computers and hard drives today dont require the sort of code hand tuning that was required 5 years ago.
The function itself isnt that important, its the concepts were dealing with here. If youve got functions already in other apps that you think might be useful to reuse then the easiest way to get them is to use the "Import from Application" option which is in the File menu of the Clarion IDE.
Theres one important step to note when creating (or importing) functions. You must explicitly set the NAME attribute in the functions prototype. For example the Calendar function takes a long, and returns a long. So its prototype would normally be "(Long), Long". However when creating a DLL you need to add the Name attribute to the end. So it becomes "(Long), Long, Name (Calendar)". You need to do this to stop the compiler "mangling" the name for you, which would make the function unusable in this DLL. Also when we prototype the function in the application where it will be used then we need to add the DLL attribute. Well see that later.
Before we go ahead an compile the application theres one more item to set. Go to the project settings, down to the bottom where it says "Target Name". Remove the name thats there for you (in my case it was CS.DLL) and add a name built up as follows; CW2<your app>16.DLL. So mine became CW2CS16.DLL. Now you see the reason for keeping our original application name to 3 characters. The point here is that we want to reuse this library which almost certainly means well be compiling "Local" versions as well as 32-bit versions. Ill talk about this more, later. Also were going to port this library to later versions of Clarion (starting with the impending Clarion 4) so we need some kind of naming standard. The simplest thing to do is use the same standard Clarion does.
If you compile at this point ( go ahead try it ) youll get an error saying something like "Make Error: File "CW2CS16.EXP" not found" . This .EXP file is the Export file. Its from this file that Clarion makes the Library that goes with your DLL. The library contains all the necessary information for later applications to use the DLL. All however is not lost. In fact this little step is a major bonus which well see in a minute. Its also the reason we dont name our app originally as "CW2CS16.APP".
Load up the EXP file that is there (which has the name <yourapp>.EXP, in my case CS.EXP) into the CW editor. Mine looks something like this (yours will look similar):
LIBRARY CS CODE MOVEABLE DISCARDABLE PRELOAD DATA MOVEABLE SINGLE PRELOAD HEAPSIZE 1024 SEGMENTS ENTERCODE MOVEABLE DISCARDABLE PRELOAD EXETYPE WINDOWS EXPORTS CALENDAR @1 DAYOFTHEWEEK @2 DAYSINMONTH @3 $GlobalRequest @4 $GlobalResponse @5
Now most of this we can ignore for now, but before we save this under a new name we need to make 2 changes. Firstly change the top line to be the FULL name of your DLL (without the extension). So in my case it becomes:
LIBRARY CW2CS16
Then delete the last two lines, and indeed any others which may be at the end of the list starting with a "$".
Then save the file under its new name, which in my case is CW2CS16.EXP. For me the file ended up looking like this:
LIBRARY CW2CS16 CODE MOVEABLE DISCARDABLE PRELOAD DATA MOVEABLE SINGLE PRELOAD HEAPSIZE 1024 SEGMENTS ENTERCODE MOVEABLE DISCARDABLE PRELOAD EXETYPE WINDOWS EXPORTS CALENDAR @1 DAYOFTHEWEEK @2 DAYSINMONTH @3
Now go ahead and compile, and if there are no errors in your code then youll see those magic words "Made CW2CS16.DLL".
Now although weve successfully made a DLL we need to do a few more things to make it really useful. Remember a little time spent here will make using the DLL that much easier, which means it will get used. If youre like me then simplicity is the name of the game. If its too hard to use I simply dont use it.
Ok, so 2 things left to do. The first is to document your functions, and the second is create a simple template to use them. There, in one sentence Ive managed to capture the two things Clarion programmers would prefer to ignore. Keep reading though, it really isnt as hard as you think.
Theres not much I can do about the first except to give you these tips.
Use a simple Windows editor to store your documentation. That means for Windows 3.1 users, use Write and for Windows 95 users use WordPad (or even better - use Write. You can copy Write from your old copy of Windows, put it in your \Windows directory, create a shortcut to it, and it works just fine). The main reason for this is size and portability. Sure youve got that Word 95 just sitting there looking at you but Word takes oodles of RAM to load, which means less for Clarion when youre compiling. So save Word for those long manuals. Also you may need to distribute your library to others and Write and WordPad provide the most portable ways of doing this.
Be brief in each functions description. Capture the function name, the parameters it takes, what it returns, and what it does. Keep it short and to the point. Write down anything special about the function, but dont spend too long detailing the obvious.
There is much that could be said about writing templates, but the idea here is to keep it simple. The more time you spend writing the template the more you save later. However the effort of learning the template language can often offset the benefit gained. Well explore the templates in a later column but for now lets concentrate on the basics. Remember we dont need the template for compiling the DLL, we need it for the applications that will eventually use the DLL.
Using templates we can simplify the use of the DLL in the following ways:
For the purposes of this article we will deal with only the first 2 parts. The third will be discussed in a later article. In the meantime the first 2 will be sufficient and will allow you to use your new functions in any embedded source code.
Firstly our template file needs a name. No big deal here, Im going to call mine CS.TPL. In it Im going to create a single Global Extension Template. By adding the global extension to any application the functions in our library (as detailed in the template) will be added to the application. Dont worry if youre not a template expert (or even if youve never seen template code before). You should be able to edit my example file sufficiently for your purposes.
#TEMPLATE (CapeSoft, 'Common Library functions')
#!==========================================================
#EXTENSION Activate_CapeSoft,'Activate Common Library'),APPLICATION
#!----------------------
#AT(%CustomGlobalDeclarations)
#IF(%Target32)
#PROJECT('Cw2Cs32.Lib')
#ELSE
#PROJECT('Cw2Cs16.Lib')
#ENDIF
#ENDAT
#!------------
#AT(%GlobalMap)
Module('CS')
Calendar (Long), Long, Name ('Calendar'), DLL(dll_mode)
DayOfTheWeek (Long), Long , Name ('DayOfTheWeek'), DLL(dll_mode)
DaysInMonth (Long, Long ), Long , Name ('DaysInMonth'), DLL(dll_mode)
End
#ENDAT
#!---------
Thats it, thats the whole file.
There are only two parts that might need changing. The name of your DLL as mentioned in the first part (although note that even a DLL gets a .LIB extension in a project). The second part is the prototypes of all the functions. As you can see Ive grouped them together in one module. The name of the module itself is not used, so I prefer the name of the original app. Dont use the Cw2Cs16 construction here. The prototypes themselves I cribbed from the main source code file of my DLL app (Cs.Clw) with one addition.
The DLL attribute is required for 32-bit programs. It wont matter too much if you leave it out and youre only compiling your application in 16-bit, but any template should be sufficient for both 16 and 32-bit programs. This makes it easy to change your application from 16 to 32-bit later.
Dont forget to save this file in your \cw20\template directory and also to register the new template in your template registry. Also remember to copy your new DLL from your development directory to your \cw20\bin directory.
As you might have spotted in the above template file, the template allows for a 16 and 32-bit version of your DLL. To recompile your DLL as a 32-bit DLL requires just four changes:
When you add a new function to your library youll need to do the following:
Now you can use your functions in embedded or source code just as if they were part of the Clarion language without having to worry about including the correct libraries or prototyping the functions correctly. All you do is add your new global extension to your application and code away!
Weve now covered all the basic information you need to know to make and maintain your own function library. Remember the basics: write the code, document it and then do the template. It really will make your coding life that much easier.
Copyright © 1999-2008 by CoveComm Inc. All Rights Reserved. Reproduction in any form without the express written consent of CoveComm Inc., except as described in the subscription agreement, is prohibited.
Clarion Magazine ISSN 1718-9942
One year: $184
(includes all back issues since '99)
Renewals from $134
Two years: $274
Renewals from $224