help files
Z505 | PasWiki | FUQ | Search | Main Docs | API Guide



Notes

This page explains some definitions and differences between pwumain.pas and dynpwu.pas.

Dynamic vs Static

Compiling functions into your program is static. When you request that a function be called from an external library module (DLL on windows, SO or DSO on Unix), this is dynamic.

DynUnit.pas vs Unit.pas

We've named the units UNIT.PAS and any dynamic wrappers are called DYNUNIT.PAS. For example any unit prefixed with DYN at the beginning generally means that the unit is just a dynamic DLL wrapper unit. Pwumain is the main web utilities unit, while dynpwu.pas is a dynamic wrapper that calls a DLL. Dynpwu is equivalent to pwumain except dynpwu calls a library while pwumain contains functions that are linked into your executable.

Using The Dynamic Library

If you are using the dynamic version of the web utilities, you will also have to upload the dynamic link library once to a common directory. The web programs will be smaller since much of the code is stored in a single DLL/SO.

If you choose not to use the library, code will be compiled in statically and your executable will be a bit bigger in size to upload. For most people it is not a big deal.

If you chose not to upload the library to your server, simply put the pwumain unit in your uses clause. In some programs, you might want to switch between using the library and the static compilation. You could use a {$IFDEF STATIC} directive in the uses clause and define STATIC when using pwumain if you wanted.

For example, if you are compiling your program with pwumain and not dynpwu:

  fpc prog.pas -dSTATIC -B
The -dSTATIC option could tell other units that rely on the main functions to use pwumain instead of dynpwu. The -B option would ensure rebuilding of all the units. If you look at some of the units in the /extras/ folders that rely on the main functions, you will notice this:
  uses
    {$ifdef STATIC}
     pwumain;
    {$else}
     dynpwu;
    {$endif}
You do not have to add this ifdef if you plan on always using static mode or dynamic mode only. If you ever wish to switch between using the library or using static compilation, this ifdef switch can help.

BSD Libraries

At current time of writing (FPC 2.0.4), the BSD operating system has been tested with pwumain, but will not work with dynpwu. This is due to a freepascal compiler issue for BSD only.

Other Notes

-------------------------------------------------------------------------------
What is the power of a library versus static compiling right into the CGI?
-------------------------------------------------------------------------------
The power of a dynamic library is

 * the size of the cgi program is smaller and easier to upload for you,
   since most of the grunt work is in the Powtils/psp DLL (library) in your cgi 
   directory on the server. You upload the DLL once and only upload your
   small cgi programs that use the library.

 * compile cgi programs faster. Since the Powtils core is not recompiled 
   each time you create a cgi program, only your code that wraps around and 
   talks to the library is compiled. Just the import declarations are compiled, which
   takes much less time than compiling pwumain.  

 * compile cgi programs using less include and unit search paths. 

 * the ability for very busy hours of your website to use less memory.
   The more visitors that hit your website at once (simutaneously) the more
   memory is used. With the DLL, less memory is used because of the
   way operating systems make use of dynamic link libraries (both unix like and
   windows operating systems). This topic is complicated, but the summary
   is that when a dll is called while several visitors are hitting your site
   at the same time, less memory in the end is used than if you had static 
   code. 

 * special pwu-1.6-debug.dll available. Simply change your config file to point 
   to a special debug version of pwu-1.6 dll and it will give you verbose 
   reporting immediately. In static pwu, you would have had to recompile the 
   entire pwumain unit with a -dPWUDEBUG or -dDEBUG_ON compiler switch, and reupload 
   the cgi program, which could be more tedious.

The disadvantage of a dynamic library is:

 * when your website is not so busy, the cgi program has to call upon the DLL
   which may end up using slightly more memory than if you had statically
   compiled the code into the cgi program. 
 
 * exceptions or access violations may be harder to debug inside a DLL
  
 * your IDE will take you to the dll wrapper unit when you use the "find 
   declaration" tool if your IDE supports this. The wrapper unit will not lead 
   you to the actual source code of Powtils, just the library import declarations. 
   STATIC will have to be defined in your  unit if you want to be 
   taken to the actual source code of pwumain. This could be solved by a plug-in of 
   some sort - an IDE could work around issues.

 * DLL hell - if you upgrade your DLL without changing your config file and you 
   delete the old DLL, the program will complain asking you for the correct DLL to be 
   installed, or it may exit with a 500 error (or even an internal fpc exception) in 
   versions which we did not have DLL version detection system in place.

 * Global config file issues - if you upgrade your DLL path in the global config 
   file, some of your programs that were compiled against a different verison will 
   not work until you upload a local config file specifying which DLL to use.

   For example if you compiled a program with version 1.6.0.1 of dynpwu.pas and then 
   upgraded the global config file on line one to point to 1.6.0.2 dll, the compiled 
   program will not run becuase it expects a 1.6.0.1 dll.  Uploading the old 1.6.0.1 
   dll and adding a local config file to that cgi program directory will solve the 
   problem, or you can recompile the old 1.6.0.1 program with a 1.6.0.2 version of 
   dynpwu.pas

Why does Dynpwu work?

You might be wonder how dynpwu really works? How can it use reference counted ansistrings inside the DLL without causing memory problems or dangling references?

A common memory manager is used. The memory manager is exported and then imported using GetMemoryManager() and SetMemoryManager() calls. No Cmem or Sharemem is used since the memory manager is shared within the lib/exe itself.






lufdoc, Powtils, fpc, freepascal, delphi, kylix, c/c++, mysql, cgi web framework docs, Z505