You should write your DLL using the simple rules described in the next paragraph. The DLL must be written with a 32-bit compiler such as Microsoft Visual C++ or Borland's Delphi (release 2 or higher). If written in C++, the entry point should be declared using C syntax.

Your DLL entry points should each take three parameters: two integers representing the line number and call number (both passed by value), and a null-terminated UTF8-encoded string parameter (passed by reference, as usual). In your DLL, you may place a new null-terminated value (up to 8192 characters) at the address passed for the string parameter and retrieve it later as a CopiaFacts variable. CopiaFacts can also use the numeric integer result returned by your DLL. You may have any number of such entry points in a DLL, and you may load up to 8 DLLs. Each loaded DLL is available to all CopiaFacts lines on the node.

To use parameters with system default encoding, or with Unicode (UTF-16) encoding, see the topic on Alternate Parameter Encoding.

You assign a number between 1 and 8 to your DLL and name it on a $load_dll command in the CopiaFacts configuration file. You may assign different DLLs for each node in your system. To load two DLLs on node M1, the following commands should appear in your configuration file:

$load_DLL M1 1 validate.dll

$load_DLL M1 2 lookup.dll

If you work with several loaded DLLs, you can use variables to replace the DLL numbers, to make your infoboxes easier to maintain. Your configuration file would then read as follows:

$load_DLL M1 1 validate.dll VALDLL

$load_DLL M1 2 lookup.dll LOOKDLL

Then when you come to select the look-up DLL in the infobox from which it is called, you can write either of the following statements:

$set_var DLL_SELECT 2          ; use lookup.dll

$set_var DLL_SELECT @LOOKDLL   ; use lookup.dll

You may make a DLL call using a single Infobox. Unlike $get_var, where the result is not available until the next box, the DLL result is available immediately.

; sample DLL call infobox

$type decision

$set_var DLL_SELECT 1          ; select validate.dll

$set_var DLL_PARM @usercode    ; pass in code from caller

$set_var DLL_CALL ValEntry     ; call the DLL procedure

$if @DLL_RETURN < 0              ; call error

  $set_var errorcode @DLL_PARM   ; save error code

  $next_box 1234                 ; handle error

$else

  $if @DLL_RETURN = 0            ; validation OK

    $set_var DLL_PARM @userid    ; pass in another code

    $set_var DLL_CALL Lookup     ; call another procedure

    $if @DLL_RETURN < 0

      $set_var errorcode @DLL_PARM

      $next_box 1235

    $else

      $set_var fullname @DLL_PARM ; returned by DLL

      $next_box 12                ; normal return

    $endif

  $else                         ; validation error

    $next_box 13

  $endif

$endif

In the example above, remember that $next_box is not the same as a "go to" in a program. It merely sets the place to go to on completion of processing or this infobox. Also, if you assign @DLL_RETURN to your own variable, remember to use the "=" option of $set_var. If the return value is negative, then without this your variable will be decremented instead of having the value assigned to it.

Your DLL must be written to be thread-safe. It may be called simultaneously by multiple threads (with different values of the passed line number), so any global static variables should either be indexed using the passed line number, or protected by a Mutex or Critical Section. CopiaFacts provides a single 8192-byte buffer for each line, which is shared by all loaded DLLs. The first byte is set to zero during line reset (between calls) but otherwise the buffer contents are retained across calls, apart of course from any data inserted by your infoboxes or by your DLLs.