home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / calldll.zip / README < prev   
Text File  |  1996-02-05  |  22KB  |  506 lines

  1. CALLDLL.ZIP contains 3 DLL's that allow you to do I/O on Micro Focus
  2. indexed (VSAM) files using REXX.  The files can be ASCII or EBCDIC,
  3. fixed or variable.
  4.  
  5. You can also create 16 bit DLL's using Micro Focus COBOL, and use this
  6. package to call them from REXX.
  7.  
  8. CALLDLL.ZIP is a shareware package.  You are free to try it for a while.  If
  9. it meets your need, the cost is $29.00 for a single PC, or $199.00 for a
  10. site license.  To register your copy, please send a check of money order to:
  11.  
  12.     GCH Software
  13.     300 Walnut, #52
  14.     Des Moines, IA 50309
  15.  
  16. Include the following information:
  17.  
  18.     Package: CALLDLL.ZIP
  19.  
  20.     Company: _______________________________
  21.  
  22.        Name: _______________________________
  23.  
  24.     Address: _______________________________
  25.  
  26.        City: _______________________________
  27.  
  28.       State: _______________________________
  29.  
  30.         Zip: _______________________________
  31.  
  32.       E-MAIL: _______________________________
  33.  
  34. Until you register your copy, the following message will appear each time
  35. you load the DLL's into REXX:
  36.  
  37.     /***************************/
  38.     /*  CALLDLL - Version 1.0  */
  39.     /*                         */
  40.     /*  Unregistered copy      */
  41.     /*                         */
  42.     /*  Functions loaded       */
  43.     /***************************/
  44.  
  45. If you include your e-mail address when registering, instructions for
  46. disabling the nag screen will be sent via e-mail.  If you do not include
  47. your e-mail address, instructions will be sent via snail mail.
  48.  
  49. If you purchase a site license, your are free to distribute any or all
  50. of the files in the package to anyone at your site.  If you do not
  51. purchase a site license, you are free to distribute the package to others
  52. provided you distribute the entire package including the including the
  53. readme file, the DLL's, and examples.
  54.  
  55. If you have any questions about the package or want to report a bug,
  56. please send e-mail to ghandy@dsmnet.com.
  57.  
  58. Here is the disclaimer:
  59.  
  60.     This package is distributed as is, without any warranty or guarantees
  61.     of any kind, either expressed or implied. You are solely responsible
  62.     for the results of the use of this package. Should the package prove
  63.     defective, you assume the entire cost of all necessary servicing,
  64.     repair, or correction.
  65.  
  66.     The author shall not be liable for any direct, indirect, consequential,
  67.     or incidental damages arising out of the use or inability to use this
  68.     package.
  69.  
  70. The following programs and files are included in CALLDLL.ZIP:
  71.  
  72.     README       - the file you are reading now
  73.  
  74.     CALLDLL.DLL  - you register and call this DLL in your REXX programs
  75.     CTOCOBOL.DLL - called by CALLDLL.DLL as an interface to COBOL programs
  76.     INDEXIO.DLL  - called by CTOCOBOL.DLL to do I/O on indexed files
  77.  
  78.     EXAMPLE.CBL  - source for a COBOL program that can be called by CALLDLL
  79.     EXAMPLE.CMD  - uses Micro Focus COBOL to compile EXAMPLE.CBL into a DLL
  80.     EXAMPLE.DLL  - DLL created by running EXAMPLE.CMD to compile EXAMPLE.CBL
  81.     DIVIDE.CMD   - uses CALLDLL.DLL to call EXAMPLE.DLL
  82.  
  83.     ASCFIXED.CMD - example of I/O on ASCII, fixed, indexed files
  84.     ASCFIXED.DAT - an ASCII, fixed, indexed file used by ASCFIXED.CMD
  85.     ASCFIXED.IDX - the index for ASCFIXED.DAT
  86.  
  87.     EBCFIXED.CMD - example of I/O on EBCDIC, fixed, indexed files
  88.     EBCFIXED.DAT - an EBCDIC, fixed, indexed file used by EBCFIXED.CMD
  89.     EBCFIXED.IDX - the index for EBCFIXED.DAT
  90.  
  91.     ASCVARBL.CMD - example of I/O on ASCII, variable, indexed files
  92.     ASCVARBL.DAT - an ASCII, variable, indexed file used by ASCVARBL.DAT
  93.     ASCVARBL.IDX - the index for ASCVARBL.DAT
  94.  
  95.     EBCVARBL.CMD - example of I/O on EBCDIC, variable, indexed files
  96.     EBCVARBL.DAT - an EBCDIC, variable, indexed file used by EBCVARBL.DAT
  97.     EBCVARBL.IDX - the index for EBCVARBL.DAT
  98.  
  99. You must place CALLDLL.DLL, CTOCOBOL.DLL, and INDEXIO.DLL in a directory
  100. specified in the LIBPATH statement of your CONFIG.SYS file.  If you cannot
  101. find a better place, you can put them in your C:\OS2\DLL directory.  If
  102. you would like to try EXAMPLE.DLL it must also be placed in a LIBPATH
  103. directory.
  104.  
  105. CALLDLL.DLL and CTOCOBOL.DLL are the nucleus of this package.  They allow
  106. Rexx to call 16 bit DLL's created with Micro Focus COBOL.  INDEXIO is a
  107. 16 bit DLL that was created with Micro Focus COBOL.  It allows you to
  108. perform I/O on a Micro Focus indexed file.
  109.  
  110. The source code for INDEXIO is not included in this package, however,
  111. EXAMPLE.CBL is provided as an example of a COBOL program that can be
  112. compiled into a 16 bit DLL and called from REXX by CALLDLL.DLL.
  113. EXAMPLE.CMD will compile EXAMPLE.CBL into EXAMPLE.DLL using Micro
  114. Focus COBOL. DIVIDE.CMD uses CALLDLL to call EXAMPLE.DLL.
  115.  
  116. Note:  Version 4.0 of Micro Focus COBOL is a 32 bit system.  Prior
  117.        versions are 16 bit systems.  A version of this package that
  118.        supports 32 bit DLL's will be release later.  Registered users
  119.        of the 16 bit version may use the 32 bit version for no
  120.        additional charge.
  121.  
  122. ASCFIXED.CMD, EBCFIXED.CMD, ASCVARBL.CMD, and EBCVARBL.CMD are examples
  123. of REXX command files that use INDEXIO.DLL to do I/O on Micro Focus
  124. indexed files.  The 4 command files are very similar. Each contains
  125. examples of opens, reads, writes, rewrites, erases, positions, sequential
  126. reads, and closes.  They each do I/O on a different type of file:
  127.  
  128.     ASCFIXED.CMD - does I/O on an ASCII fixed block file
  129.     ASCVARBL.CMD - does I/O on an ASCII variable block file
  130.     EBCFIXED.CMD - does I/O on an EBCDIC fixed block file
  131.     EBCVARBL.CMD - does I/O on an EBCDIC variable block file
  132.  
  133. ASCFIXED.CMD, EBCFIXED.CMD, ASCVARBL.CMD, and EBCVARBL.CMD are ready
  134. to run.  Just make sure the DLL's are in a LIBPATH directory, and make
  135. sure the following files are in the current directory:
  136.  
  137.     ASCFIXED.DAT
  138.     ASCFIXED.IDX
  139.     EBCFIXED.DAT
  140.     EBCFIXED.IDX
  141.     ASCVARBL.DAT
  142.     ASCVARBL.IDX
  143.     EBCVARBL.DAT
  144.     EBCVARBL.IDX
  145.  
  146. Prior to calling a 16 bit COBOL program, you must register CALLDLL.DLL
  147. with REXX:
  148.  
  149.     if RXFUNCQUERY('CallDLLLoadFuncs') then do
  150.         call RXFUNCADD 'CallDLLLoadFuncs', 'CALLDLL', 'CallDLLLoadFuncs'
  151.         call CallDLLLoadFuncs
  152.     end
  153.  
  154. Note:  'CallDLLLoadFuncs' must be entered exactly as shown above, or it can
  155.        be entered in all caps.  Other combinations of upper and lower case
  156.        letters are not valid.
  157.  
  158. You can unregister CALLDLL.DLL by making the following call from your
  159. REXX program
  160.  
  161.     call CallDLLDropFuncs
  162.  
  163. Note:  'CallDLLDropFuncs' must be entered exactly as shown above, or it can
  164.        be entered in all caps.  Other combinations of upper and lower case
  165.        letters are not valid.
  166.  
  167. CALLDLL.DLL takes 3 parameters: the name of the 16 bit DLL to call, and
  168. the names of two parameters.  For example:
  169.  
  170.     call CallDLL 'INDEXIO', 'ComArea', 'VSAMRecord'
  171.  
  172. Another example would be:
  173.  
  174.     call CallDLL 'EXAMPLE', 'FirstParameter', 'SecondParameter'
  175.  
  176. Note that 'ComArea', 'VSAMRecord', 'FirstParameter', and 'SecondParameter'
  177. are in quotes.  You are passing the names of the parameters to CALLDLL,
  178. not the parameters themselves. CALLDLL gets the parameters by calling
  179. the RexxVariablePool function. It then calls the 16 bit DLL, passing
  180. the parameters.  After the 16 bit DLL ends, CALLDLL uses the
  181. RexxVariablePool function to put the parameters returned from the DLL
  182. back into the REXX variables.
  183.  
  184. Prior to doing any I/O on an indexed file, the file must be opened.  Here
  185. is an example of an open call:
  186.  
  187.     ComArea = '00' || left('ASCFIXED.DAT', 100) || 'F'
  188.     call CallDLL 'INDEXIO', 'ComArea', 'VSAMRecord'
  189.  
  190. The first parameter (ComArea) tells INDEXIO what type of I/O you would
  191. like to perform.  In this case you are telling INDEXIO to open the fixed
  192. block file "ASCFIXED.DAT" for input.
  193.  
  194. After opening the file, you could use the following code to read a record:
  195.  
  196.     key = left('Sue', 100)
  197.     ComArea = '20' || left('ASCFIXED.DAT', 100) || 'F' || key
  198.     VSAMRecord = left('', 80)
  199.  
  200.     call CallDLL 'INDEXIO', 'ComArea', 'VSAMRecord'
  201.  
  202. This time, the first parameter (ComArea) tells INDEXIO to perform a random
  203. read on "ASCFIXED.DAT".  The record with a key of "Sue" is read and placed
  204. into the REXX variable "VSAMRecord".  After making the call, you could use
  205. the REXX command "SAY" to write the record to the screen:
  206.  
  207.     say 'The record returned from the random read was' VSAMRecord
  208.  
  209. It is always good to close the file after doing I/O.  The file will
  210. remain open until it is closed, or until the session that opened the
  211. file is closed.  A file that was opened for I/O will be tied up until
  212. the file is closed:  you will not be able to rename or delete the file,
  213. and you will not be able to modify the file using the Micro Focus Data
  214. File Editor.  However, other COBOL programs, such as INDEXIO.DLL can
  215. update the file while another process has it open for I/O.
  216.  
  217. The following statements close the ASCFIXED.DAT file:
  218.  
  219.     ComArea = '90' || left('ASCFIXED.DAT', 100) || 'F'
  220.     call CallDLL 'INDEXIO', 'ComArea', 'VSAMRecord'
  221.  
  222. Looking at the examples above, notice that when opening the file, the
  223. first byte of the ComArea was "0".  When doing a random read, the first
  224. byte of the ComArea was "2".  When closing the file, the first byte of
  225. the ComArea was "9".  The first byte of the ComArea is referred to as
  226. the call code.  Here are the currently supported call codes that can
  227. be passed to INDEXIO.DLL:
  228.  
  229.     0 - Open for input
  230.     Q - Open for I/O
  231.     2 - Random read
  232.     4 - Write or Rewrite
  233.     5 - Rewrite or Write
  234.     E - Erase
  235.     P - Position (greater than or equal to key)
  236.     1 - Read sequential (from beginning of file, or the last position)
  237.     9 - Close file that was opened for input or I/O
  238.  
  239. The call codes are case sensitive.  A "P" call code is valid, but a
  240. "p" call code is not. The call codes are explained in more detail
  241. later in this document.
  242.  
  243. The second byte of the ComArea is the return code.  It is set by
  244. INDEXIO.DLL and indicates the success or failure of the attempted
  245. operation.  It is a good idea to check the return code after each
  246. call to INDEXIO.DLL and take appropriate action if the call was
  247. unsuccessful. Here are the possible return codes:
  248.  
  249.     0 - Request successfully processed
  250.     9 - Attempting to read past end of file on a sequential read
  251.     B - Key definition block for the file is too big
  252.     F - File not found
  253.     G - Error reading file header
  254.     I - Invalid info passed in the ComArea
  255.     N - Record not found on random read or erase
  256.     O - Error opening file
  257.     E - Other error
  258.  
  259. Normally, you will only receive the B, F, G, and O return codes when
  260. opening the file.  The 9 return code should only occur on a sequential
  261. read.  The N return code should only occur for random reads, positions,
  262. or erases.  The 0, I, or E return codes can occur on any type of call.
  263.  
  264. Bytes 3 through 102 (100 bytes total) of the ComArea is the name of
  265. the file to perform the I/O on.  If no path is specified, the current
  266. directory will be assumed.  The file name must be name of the data
  267. portion of the indexed file, not the name of the index portion.  The
  268. file name may be entered in upper or lower case.  If the file name is
  269. less than 100 bytes, it must be padded with spaces on the right. An
  270. easy way to pad a file name with spaces is:
  271.  
  272.     FileName = 'C:\FILES\MYFILE.DAT'
  273.     FileName = left(FileName, 100)
  274.  
  275. Byte 103 of the ComArea is either "F" if you are doing I/O on a
  276. fixed block file, or "V" if you are doing I/O on a variable block
  277. file.  If you pass in any other value, an "I" call code will be
  278. returned.  When reading variable block files, INDEXIO appends the
  279. 5 byte record length to the beginning of the record prior to passing
  280. the record back to REXX.  For example:
  281.  
  282.     00038Taunya  9876 3rd St.    Dallas      TX
  283.  
  284. When writing or rewriting variable block records, you must append
  285. the 5 byte record length to the beginning of the record prior to
  286. calling CALLDLL.  For example:
  287.  
  288.     0038Taunya  9876 3rd St.    Dallas      TX
  289.  
  290. An easy way to append the record length is:
  291.  
  292.     VSAMRecord = 'Taunya  9876 3rd St.    Dallas      TX'
  293.     VSAMRecord = right(length(VSAMRecord), 5, '0') || VSAMRecord
  294.  
  295. Bytes 104 through 203 (100 bytes total) is the key of the record.
  296. The key is case sensitive.  You must pass in a key for the following
  297. call codes:
  298.  
  299.     2 - Random read
  300.     E - Erase
  301.     P - Position (greater than or equal to key)
  302.  
  303. If the key is less than 100 bytes, it must be padded with spaces on
  304. the right. An easy way to pad the key with spaces is:
  305.  
  306.     key = 'Taunya'
  307.     key = left(key, 100)
  308.  
  309. The last byte in the ComArea (byte 204) tells INDEXIO.DLL if the
  310. file is ASCII or EBCDIC. Set byte 204 to "Y" for EBCDIC files, or
  311. some other value of ASCII files.  Since REXX expects data to be
  312. ASCII,  INDEXIO will be automatically convert data between ASCII
  313. and EBCDIC when appropriate.  For example, when writing a record
  314. to an EBCDIC file, INDEXIO will convert the record to EBCDIC prior
  315. to writing to the file.  When doing a random read, INDEXIO will
  316. convert the record to ASCII prior to passing it back to the REXX
  317. program.
  318.  
  319. Note:  The ASCII/EBCDIC switch must be in byte 204.  If you are
  320. doing a sequential read on an EBCDIC file, you would not normally
  321. pass a key.  However, if you do not, the EBCDIC/ASCII switch will
  322. not be in column 204.  So, it is necessary to pass in a key when
  323. doing sequential reads on an EBCDIC file to ensure the ASCII/EBCDIC
  324. switch is in byte 204.
  325.  
  326. Following is a more detailed description of the call codes.  The
  327. call code is case sensitive.  The call code "P" is valid, but the
  328. call code "p" is not.
  329.  
  330. The "0" call code opens a file for input.  Opening for input will not
  331. tie up the file.  Use the "0" call code to open files if you are only
  332. going to read the file.  Opening the file for input, allows you to
  333. do random reads, positions, or sequential reads, but it will not
  334. allow you to do writes, rewrites, or erases.
  335.  
  336. The "Q" call code opens a file for input or output.  Opening a
  337. file for input/output (I/O), allows you to do random reads, positions
  338. sequential reads, writes, rewrites, or erases.  Opening a file for I/O
  339. will tie up the file.  While the file is opened for I/O, COBOL program
  340. running in other sessions (including INDEXIO.DLL) can update the file,
  341. but the Micro Focus Data File Editor cannot be used to update the file.
  342. For this reason, you should always close files that were open for I/O,
  343. even if an error condition occurs when processing the file.
  344.  
  345. The "2" call code does a random read on the file.  You must open the
  346. file for input or I/O prior to doing a random read.  When doing a
  347. random read, you pass the key of the record to be read. A random read
  348. returns the record if the call was successful, or a nonzero return
  349. code if the call was unsuccessful.  For example, if you try to read a
  350. record that does not exist, you will get an "N" return code.
  351.  
  352. The "4" call code writes a new record to the file.  If the write is
  353. unsuccessful (most likely because the record already exists in the
  354. file), a rewrite will be attempted.  If the rewrite is also unsuccessful,
  355. the return code will be set to "E". Prior to doing a "4" call code, the
  356. file must be opened for I/O.
  357.  
  358. The "5" call code rewrites a record that already exists in the file.
  359. If the rewrite is unsuccessful (most likely because the record does
  360. not exists in the file), a write will be attempted.  If the write is
  361. also unsuccessful, the return code will be set to "E". Prior to doing
  362. a "5" call code, the file must be opened for I/O.
  363.  
  364. The '4' and '5' call codes are almost interchangeable.  You can use
  365. either to do a write or a rewrite.  However, performance will be a
  366. little better if you select the correct call code based on whether
  367. the record already exists in the file or not.
  368.  
  369. The "E" call code erases a record.  You pass the key of the record to
  370. be erased in the ComArea.  If the record does not exist, the return
  371. code will be set to "N".  Prior to doing an "E" call code, the file must
  372. be opened for I/O.
  373.  
  374. The "P" call code returns the record that is greater than or equal to
  375. the key, and it sets the sequential pointer to the next record in the
  376. file.  After positioning, sequential reads will return records that come
  377. after the record that was positioned on.  Prior to doing a "P" call code,
  378. you must open the file for input or I/O.  The "P" call code is similar
  379. to a random read because it returns a record.  However, a random read
  380. requires that you specify the exact key that you want to read, while
  381. the position allows you to specify the first few bytes of the key.
  382.  
  383. The '1' call code reads sequentially through the file.  If you do not
  384. do a position prior to the sequential read, the first record in the file
  385. will be returned.  Subsequent sequential reads will return subsequent
  386. records in the file.  If you do a position prior to a sequential read,
  387. the record returned will be the record that comes after the record that
  388. was positioned on. After all records in the file have been read, the
  389. next sequential read will result in a "9" return code. Prior to doing
  390. a "1" call code, you must open the file for input or I/O.
  391.  
  392. The "9" call code closes files that were opened for input or I/O.  It
  393. is very important that you close files because the files remain open
  394. until they are closed, or until you close the session that opened the
  395. file.  If you do not close a file that was opened I/O, the Micro Focus
  396. Data File Editor cannot be use to update the file until it is closed,
  397. however, COBOL programs (such as INDEXIO.DLL) running in other sessions
  398. can update the files.
  399.  
  400. Some things to remember about INDEXIO.DLL:
  401.  
  402.     When you read a variable length record, INDEXIO appends the 5 byte
  403.     record length to the beginning of the record prior to passing it
  404.     back to your REXX program. For example:
  405.  
  406.       00090Taunya  9876 3rd St.    Dallas      TX
  407.  
  408.     When you write or rewrite a variable length record, the REXX program
  409.     must append the 5 byte record length to the beginning of the record
  410.     prior to calling INDEXIO. For example:
  411.  
  412.         00038Taunya  9876 3rd St.    Dallas      TX
  413.  
  414.     The length function can be used to simplify the task of appending
  415.     the record length:
  416.  
  417.         VSAMRecord = 'Taunya  9876 3rd St.    Dallas      TX'
  418.         VSAMRecord = right(length(VSAMRecord), 5, '0') || VSAMRecord
  419.  
  420.     A position returns a record and sets the sequential pointer to the
  421.     record after the record that was positioned on.
  422.  
  423.     When doing I/O on EBCDIC files, the REXX program always works with
  424.     ASCII data.  INDEXIO does the converting from EBCDIC to ASCII and
  425.     ASCII to EBCDIC.
  426.  
  427.     It is very important that you close the files after you have finished
  428.     performing I/O on them.
  429.  
  430.     A REXX command file can do I/O on only 1 indexed file at a time.
  431.     If you need to perform I/O on two different files within the same
  432.     command file, you must open, process, and close the first file
  433.     before processing the second file.
  434.  
  435.     Performance is pretty good.  INDEXIO takes approximately 0.04
  436.     seconds to perform a random read, and about 0.07 seconds to do
  437.     a write or a rewrite.  Opening a file takes around 0.3 seconds.
  438.     These numbers are based on a 486/33 processor with the files on
  439.     the local drive.
  440.  
  441. As mentioned above, you can compile a COBOL program into a 16 bit DLL
  442. using Micro Focus COBOL (version 3.2 or earlier) and call it using
  443. CALLDLL.DLL.
  444.  
  445. Prior to calling a 16 bit COBOL program, you must register CALLDLL.DLL
  446. with REXX:
  447.  
  448.     if RXFUNCQUERY('CallDLLLoadFuncs') then do
  449.         call RXFUNCADD 'CallDLLLoadFuncs', 'CALLDLL', 'CallDLLLoadFuncs'
  450.         call CallDLLLoadFuncs
  451.     end
  452.  
  453. Note:  'CallDLLLoadFuncs' must be entered exactly as shown above, or it can
  454.        be entered in all caps.  Other combinations of upper and lower case
  455.        letters are not valid.
  456.  
  457. You can unregister CALLDLL.DLL by making the following call from your
  458. REXX program
  459.  
  460.     call CallDLLDropFuncs
  461.  
  462. Note:  'CallDLLDropFuncs' must be entered exactly as shown above, or it can
  463.        be entered in all caps.  Other combinations of upper and lower case
  464.        letters are not valid.
  465.  
  466. EXAMPLE.CBL is included in this package as an example of a COBOL program
  467. that can be called from REXX using CALLDLL. The COBOL program must have
  468. two 01 level records in the linkage section. The 01 level records can
  469. contain PIC X fields or PIC 9 fields.  They should not contain COMP-3
  470. fields or COMP fields because they are difficult to work with in REXX
  471. programs.
  472.  
  473. The REXX program that calls the DLL should format the fields in the
  474. exact format that the COBOL program is expecting them.  For example,
  475. if the COBOL program is expecting the first 01 level record to contain
  476. a 5 digit number, followed by a space, followed by another 5 digit number,
  477. the REXX program might do something like this:
  478.  
  479.     FirstParameter = '00100 00030'
  480.  
  481. If the COBOL program is expecting the second 01 level record to contain
  482. a 20 byte first name and a 20 byte last name, you might do something
  483. like the following:
  484.  
  485.     SecondParameter = left('Bob', 20) || left('Smith', 20)
  486.  
  487. You should always initialize both parameters to the correct length
  488. prior to calling CALLDLL.  This ensures that REXX has allocated
  489. enough space for the parameters and you will not be overwriting
  490. space that does not belong to your application.
  491.  
  492. After initializing both parameters, the REXX program should call
  493. CALLDLL, passing the name of the COBOL DLL to call, and the names
  494. of the parameters.  For example
  495.  
  496.     call CallDLL 'EXAMPLE', 'FirstParameter', 'SecondParameter'
  497.  
  498. CALLDLL will retrieve the parameters by calling the RexxVariablePool
  499. function, then pass the parameters to the COBOL DLL.  The COBOL DLL
  500. is free to change either of the two 01 level records, and CALLDLL will
  501. updated the REXX variables prior to returning to REXX.
  502.  
  503. See DIVIDE.CMD for an example.  It calls EXAMPLE.DLL, passing two
  504. numbers in the first parameter.  The two number are divided and the
  505. quotient and remainder are put into the second parameter.
  506.