| 
 
      This article was first published in 
	Clarion Online Volume 1, issue 1 and is reproduced here with permission.
      
     
      |  | 
		
			| The Joys of Reusable Code : Making your own Function LibraryBy Bruce Johnson
 |  |  |  
      |  |  |  |  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.
 
 
 Getting Started 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 @5Now 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 CW2CS16Then 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 @3Now 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.Prototyping our DLL functions in our appAdding the required libraries to the projectCreating small "code" or "control" templates that 
        make it easier to use the new function. 
 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:In the Project settings change the "Project Generator" properties 
        to 32-bit.Again on the project settings remove the "Target" file and 
        add a 32-bit name in its place. In my case this would be "Cw2Cs32.DLL"Create an EXP file as you did for the 16-bit version. Set the library 
        name to be the same as the 32-bit DLL. Save it with the same name as the 
        new DLL.Compile and copy your new 32-bit DLL to your \cw20\bin directory. 
      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!Add the function to the library application.Add the function name to BOTH EXP files.Add the new function name to the prototype section of the template.Copy the new DLLs to your \cw20\bin directory 
 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.
 
 
 
 © 1997 Online Publications, Inc. Reproduced 
      with permission.     
     
   
	© 2012 CapeSoft Software CC
 |