>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads

Science makes it known,
Engineering makes it work,
Art makes it beautiful.

View Rodney Roberts's profile on LinkedIn


Using Fujitsu COBOL 3.0 to call the USPS Address Matching System API

This page discusses developing a simple Win32 COBOL main program calling a C++ function(s) stored in a .DLL.   The COBOL code I developed; the C++, .DLL, and .LIB files were obtained from a third party.   In other words, this page discusses how to develop Win32 COBOL code calling functions in a 'Black Box'.  For developing a more functional Win32 GUI COBOL program calling C++ functions, see web page Combing Fujitsu COBOL 3.0, PowerCOBOL 3.0, and the USPS Address Matching System API.

Fujitsu COBOL and the USPS Address Matching System Application Programming Interface are used as the specific example.   In general, this page should be helpful to anyone developing a Fujitsu COBOL program that calls a C++ function.

While pursuing my Master's degree at Stevens Institute of Technology, I was part of a team effort investigating the possibility of becoming a Coding Accuracy Support System (CASS) vendor certified by the United States Postal Service (USPS).   The USPS provides a myriad of products and services to bulk mailers (see ribbs.usps.gov for additional information about these products/services; or download 'quick and dirty' spreadsheet listing products and descriptions from this site).   Trying to determine the CASS requirements, how to meet them, and which USPS product/service to use was challenging.

After some searching, the USPS Address Matching System Application Programming Interface (AMS API) looked promising1.   The AMS API is a Developer's Kit based on CASS guidelines used in developing address matching software (the Address Matching System Application Programming Interface User Guide is available from the ribbs site).   The AMS API functions can be used to check the integrity of an address, determine ZIP+4, and mailing list validation.   The advantage is a reduction in bulk mailing costs.   The AMS API functions (written in C++) are in the dynamic link library ZIP4_W32.DLL.

Since the proof-of-concept software was being prototyped in Fujitsu COBOL2 on a Win32 PC calling the USPS supplied AMS API 32-bit C++ functions, it added to the challenge.   Or perhaps I have been spoiled by writing COBOL main programs calling FORTRAN subroutines on midrange and mainframe machines, where the calling/linking procedures are an order of magnitude simpler than on a Win32 PC.   If its the latter, then I may be stating the obvious with this particular web page.

At any rate, permit me on giving a simple tutorial on using Fujitsu COBOL 3.0 to call C++ functions in a .DLL.   After all, it may prove useful to that one programmer who finds it necessary to develop in COBOL rather than C++.

Sample COBOL Code

Below is a listing of a test Fujitsu COBOL main program (AMSTEST.COB) to call a few of the various AMS API functions.

000010 IDENTIFICATION DIVISION.                                                       
000030 ENVIRONMENT DIVISION.                                                          
000050 DATA        DIVISION.                                                          
000080 77  DISP-STATUS           PIC -9(4).
000090 77  DMY                   PIC X(004).
000110 01  AMS-VERSION           PIC X(32).
000180     DISPLAY "Calling z4openSTD".
000220     IF Z4-AMS-API-OPEN THEN
000230       DISPLAY "Calling z4verSTD"
000250                       USING BY REFERENCE AMS-VERSION
000310       DISPLAY "Calling z4adrinqSTD"
000320       CALL "z4adrinqSTD" WITH STDCALL LINKAGE
000330                          USING BY REFERENCE AMS-API-ZIP4-PARM
000360       DISPLAY "z4adrinqSTD status" DISP-STATUS
000370       DISPLAY " Return Code          :" AMS-API-Z4P-RETCC
000380       DISPLAY " FIRM NAME            :" AMS-API-ZP4-DADL2
000390       DISPLAY " Delivery Address Xtra:" AMS-API-ZP4-DADL3
000400       DISPLAY " Delivery Address     :" AMS-API-ZP4-DADL1
000410       DISPLAY " Last Line            :" AMS-API-ZP4-DCTYA " "
000420               AMS-API-ZP4-DSTAA " " AMS-API-ZP4-ZIPC " " AMS-API-ZP4-ADDON
000430       DISPLAY " eLOT Number          :" AMS-API-ZP4-ELOT-NUM
000440               AMS-API-ZP4-ELOT-CODE
000450       DISPLAY " Carrier Route        :" AMS-API-ZP4-CRIS
000460       DISPLAY "Calling z4closeSTD"
000470       CALL "z4closeSTD" WITH STDCALL LINKAGE
000480       DISPLAY "Successfully Called z4closeSTD"
000490      ELSE
000520     END-IF.
000530     ACCEPT DMY.
000540     EXIT PROGRAM.
In this example, AMSTEST is the calling procedure.   z4openSTD, z4verSTD, z4adrinqSTD, and z4closeSTD are the called procedures in the AMS API.

The AMS API dynamic link library ZIP4_W32.DLL contains two versions of each export function - one version has the '_cdecl' calling convention, the other has the '_stdcall' calling convention.   The '_stdcall' calling convention is used with calling procedures written in non C and C++ languages.   AMSTEST uses the '_stdcall' functions3.   As can be seen above, the '_stdcall' function names are suffixed with 'STD'.


PROGRAM-STATUS is a Fujitsu COBOL 3.0 defined field with a Picture clause of PIC S9(9) COMP-5 that contains the results of the last system call.   When calling a C++ function, the function result is stored in PROGRAM-STATUS.   Variables RTRN-INT and Z4-AMS-API-INSTLD-STATUS are then used to check the value of PROGRAM-STATUS (lines 000200 through 000210).   RTRN-INT and Z4-AMS-API-INSTLD-STATUS are defined in the include file COMDATA.COB, as shown in lines 001100 through 001190 below (inapplicable definitions have been removed for brevity).
000020*       CDS Windows 
000030*       (C) COPYRIGHT Rodney Roberts 2004
000040*       Mailing List Common Data
001100 01  C-PARMS             IS GLOBAL IS EXTERNAL.
001110     05  RTRN-INT                  PIC S9(9) COMP-5.
001120     05  RTRN-INT-2                REDEFINES RTRN-INT.
001130         10  SHORT-FUNC-VALUE      PIC S9(4) COMP-5.
001140         10  FILLER                PIC  9(4) COMP-5.
001150     05  Z4-AMS-API-INSTLD-STATUS  PIC S9(4) COMP-5.
001160         88  Z4-AMS-API-NOT-INSTLD VALUE -10.
001170         88  Z4-AMS-API-OPEN       VALUE   0.
001180         88  Z4-AMS-API-UNSYNCHED  VALUE   1.
001190         88  Z4-AMS-API-EXPIRED    VALUE   2.
Since PROGRAM-STATUS is a long integer and most of the AMS API C++ functions return a short integer, it is necessary to manipulate the returned value as shown in lines 000200 through 000210 of AMSTEST before checking the call results.   The manipulation is just simply moving PROGRAM-STATUS to a item (RTRN-INT) that is redefined as a group item with two 2-byte fields (the first is signed, the second is unsigned and ignored).   The first 2-byte is then checked for the status of the call.

AMSTEST.COB sequence lines 000320 through 000330 approximate the following C++ snippet:
The "WITH STDCALL LINKAGE" clause in sequence line 000320 of AMSTEST.COB simply tells the compiler to use STDCALL linkage rules for calling the subprogram.   The "USING BY REFERENCE" clause in sequence line 000330 serves the same purpose as the "&" in the above C++ snippet.

AMS ZIP4 Parameters

AMS-API-ZIP4-PARM is a group item defined in the include file AMSZ4PRM.COB, containing elements AMS-API-ZP4-IADL1, AMS-API-ZP4-IADL2, AMS-API-ZP4-ICTYI, AMS-API-ZP4-IPRURB, AMS-API-Z4P-RETCC, AMS-API-ZP4-DADL1, AMS-API-ZP4-DADL2, AMS-API-ZP4-DADL3, AMS-API-ZP4-DCTYA, and so on.   Basically, it is a COBOL translation of the ZIP4_PARM struct defined within the header file ZIP4.H of the AMS API (both the ZIP4_PARM struct and ZIP4.H are documented in the Address Matching System Application Programming Interface User Guide, available from the ribbs site).

Below is the COBOL equivalent of the AMS API ZIP4_PARM C++ struct:

000010*     *****     *****     *****     *****     *****                             
000020*   Parameter list for z4adrinq() and z4xrfinq() calls.  Reserved               
000030*   fields are for future use, do not access these fields.  Size of this        
000040*   record cannot be changed.                                                   
000050*   NOTE:  Only fields containing +1 in the length are null terminated.         
000070 01  AMS-API-ZIP4-PARM.                                                         
000080     05  AMS-API-Z4P-INPUT-DATA.                                                
000090         10  AMS-API-Z4P-RSVD0             PIC X(004).                          
000100         10  AMS-API-ZP4-IADL1-GRP.                                             
000110             15  AMS-API-ZP4-IADL1         PIC X(050).                          
000120             15  FILLER                    PIC X(001).                          
000130         10  AMS-API-ZP4-IADL2-GRP.                                             
000140             15  AMS-API-ZP4-IADL2         PIC X(050).                          
000150             15  FILLER                    PIC X(001).                          
000160         10  AMS-API-ZP4-ICTYI-GRP.                                             
000170             15  AMS-API-ZP4-ICTYI         PIC X(050).                          
000180             15  FILLER                    PIC X(001).                          
000190         10  AMS-API-ZP4-ISTAI-GRP.                                             
000200             15  AMS-API-ZP4-ISTAI         PIC X(002).                          
000210             15  FILLER                    PIC X(001).                          
000220         10  AMS-API-ZP4-IZIPC-GRP.                                             
000230             15  AMS-API-ZP4-IZIPC         PIC X(010).                          
000240             15  FILLER                    PIC X(001).                          
000250         10  AMS-API-ZP4-IPRURB-GRP.                                            
000260             15  AMS-API-ZP4-IPRURB        PIC X(028).                          
000270             15  FILLER                    PIC X(001).                          
000280         10  AMS-API-ZP4-IADL3-GRP.                                             
000290             15  AMS-API-ZP4-IADL3         PIC X(050).                          
000300             15  FILLER                    PIC X(001).                          
000310         10  AMS-API-Z4P-RSVD1             PIC X(098).                          
000320     05  AMS-API-Z4P-RETURN-DATA.                                               
000330         10  AMS-API-ZP4-DADL3-GRP.                                             
000340             15  AMS-API-ZP4-DADL3         PIC X(050).                          
000350             15  FILLER                    PIC X(001).                          
000360         10  AMS-API-ZP4-DADL1-GRP.                                             
000370             15  AMS-API-ZP4-DADL1         PIC X(050).                          
000380             15  FILLER                    PIC X(001).                          
000390*        standardized firm name                                                 
000400         10  AMS-API-ZP4-DADL2-GRP.                                             
000410             15  AMS-API-ZP4-DADL2         PIC X(050).                          
000420             15  FILLER                    PIC X(001).                          
000430         10  AMS-API-ZP4-DLAST-GRP.                                             
000440             15  AMS-API-ZP4-DLAST         PIC X(050).                          
000450             15  FILLER                    PIC X(001).                          
000460         10  AMS-API-ZP4-DPRURB-GRP.                                            
000470             15  AMS-API-ZP4-DPRURB        PIC X(028).                          
000480             15  FILLER                    PIC X(001).                          
000490         10  AMS-API-ZP4-DCTYS-GRP.                                             
000500             15  AMS-API-ZP4-DCTYS         PIC X(028).                          
000510             15  FILLER                    PIC X(001).                          
000520         10  AMS-API-ZP4-DSTAS-GRP.                                             
000530             15  AMS-API-ZP4-DSTAS         PIC X(002).                          
000540             15  FILLER                    PIC X(001).                          
000550         10  AMS-API-ZP4-DCTYA-GRP.                                             
000560             15  AMS-API-ZP4-DCTYA         PIC X(028).                          
000570             15  FILLER                    PIC X(001).                          
000580         10  AMS-API-ZP4-ABCTY-GRP.                                             
000590             15  AMS-API-ZP4-ABCTY         PIC X(013).                          
000600             15  FILLER                    PIC X(001).                          
000610         10  AMS-API-ZP4-DSTAA-GRP.                                             
000620             15  AMS-API-ZP4-DSTAA         PIC X(002).                          
000630             15  FILLER                    PIC X(001).                          
000640         10  AMS-API-ZP4-ZIPC-GRP.                                              
000650             15  AMS-API-ZP4-ZIPC          PIC X(005).                          
000660             15  FILLER                    PIC X(001).                          
000670*        ZIP+4 addon code                                                       
000680         10  AMS-API-ZP4-ADDON-GRP.                                             
000690             15  AMS-API-ZP4-ADDON         PIC X(004).                          
000700             15  FILLER                    PIC X(001).                          
000710         10  AMS-API-ZP4-DPBC-GRP.                                              
000720             15  AMS-API-ZP4-DPBC          PIC X(003).                          
000730             15  FILLER                    PIC X(001).                          
000740*        carrier route                                                          
000750         10  AMS-API-ZP4-CRIS-GRP.                                              
000760             15  AMS-API-ZP4-CRIS          PIC X(004).                          
000770             15  FILLER                    PIC X(001).                          
000780         10  AMS-API-ZP4-COUNTY-GRP.                                            
000790             15  AMS-API-ZP4-COUNTY        PIC X(003).                          
000800             15  FILLER                    PIC X(001).                          
000810         10  AMS-API-Z4P-RESPN             PIC S9(4) COMP-5.                    
000820         10  AMS-API-Z4P-RETCC             PIC X(001).                          
000830         10  AMS-API-Z4P-ADRKEY            PIC X(012).                          
000840         10  AMS-API-Z4P-AUTO-ZONE-IND     PIC X(001).                          
000850         10  AMS-API-ZP4-ELOT-NUM-GRP.                                          
000860             15  AMS-API-ZP4-ELOT-NUM      PIC X(004).                          
000870             15  FILLER                    PIC X(001).                          
000880         10  AMS-API-ZP4-ELOT-CODE         PIC X(001).                          
000890     05  AMS-API-Z4P-PARSED-INPUT-DATA.                                         
000900         10  AMS-API-ZP4-PPNUM-GRP.                                             
000910             15  AMS-API-ZP4-PPNUM         PIC X(010).                          
000920             15  FILLER                    PIC X(001).                          
000930         10  AMS-API-ZP4-PSNUM-GRP.                                             
000940             15  AMS-API-ZP4-PSNUM         PIC X(008).                          
000950             15  FILLER                    PIC X(001).                          
000960         10  AMS-API-ZP4-PROTE-GRP.                                             
000970             15  AMS-API-ZP4-PROTE         PIC X(003).                          
000980             15  FILLER                    PIC X(001).                          
000990         10  AMS-API-ZP4-PUNIT-GRP.                                             
001000             15  AMS-API-ZP4-PUNIT         PIC X(004).                          
001010             15  FILLER                    PIC X(001).                          
001020         10  AMS-API-ZP4-PPRE1-GRP.                                             
001030             15  AMS-API-ZP4-PPRE1         PIC X(002).                          
001040             15  FILLER                    PIC X(001).                          
001050         10  AMS-API-ZP4-PPRE2-GRP.                                             
001060             15  AMS-API-ZP4-PPRE2         PIC X(002).                          
001070             15  FILLER                    PIC X(001).                          
001080         10  AMS-API-ZP4-PSUF1-GRP.                                             
001090             15  AMS-API-ZP4-PSUF1         PIC X(004).                          
001100             15  FILLER                    PIC X(001).                          
001110         10  AMS-API-ZP4-PSUF2-GRP.                                             
001120             15  AMS-API-ZP4-PSUF2         PIC X(004).                          
001130             15  FILLER                    PIC X(001).                          
001140         10  AMS-API-ZP4-PPST1-GRP.                                             
001150             15  AMS-API-ZP4-PPST1         PIC X(002).                          
001160             15  FILLER                    PIC X(001).                          
001170         10  AMS-API-ZP4-PPST2-GRP.                                             
001180             15  AMS-API-ZP4-PPST2         PIC X(002).                          
001190             15  FILLER                    PIC X(001).                          
001200         10  AMS-API-ZP4-PPNAM-GRP.                                             
001210             15  AMS-API-ZP4-PPNAM         PIC X(028).                          
001220             15  FILLER                    PIC X(001).                          
001230*        Matched primary number.                                                
001240     05  AMS-API-ZP4-MPNUM-GRP.                                                 
001250         10  AMS-API-ZP4-MPNUM             PIC X(010).                          
001260         10  FILLER                        PIC X(001).                          
001270     05  AMS-API-ZP4-MSNUM-GRP.                                                 
001280         10  AMS-API-ZP4-MSNUM             PIC X(008).                          
001290         10  FILLER                        PIC X(001).                          
001300     05  AMS-API-ZP4-PMB-GRP.                                                   
001310         10  AMS-API-ZP4-PMB               PIC X(003).                          
001320         10  FILLER                        PIC X(001).                          
001330     05  AMS-API-ZP4-PMBNUM-GRP.                                                
001340         10  AMS-API-ZP4-PMBNUM            PIC X(008).                          
001350         10  FILLER                        PIC X(001).                          
001360     05  AMS-API-Z4P-RSVD2                 PIC X(086).                          
001370     05  AMS-API-Z4P-FOOTNOTES.                                                 
001380*        zip corrected                                                          
001390         10  AMS-API-ZP4-A                 PIC X(001).                          
001400*        city/state corrected                                                   
001410         10  AMS-API-ZP4-B                 PIC X(001).                          
001420*        invalid city/state/zip                                                 
001430         10  AMS-API-ZP4-C                 PIC X(001).                          
001440*        no zip assigned                                                        
001450         10  AMS-API-ZP4-D                 PIC X(001).                          
001460*        ZIP assigned for mult response                                         
001470         10  AMS-API-ZP4-E                 PIC X(001).                          
001480         10  AMS-API-ZP4-F                 PIC X(001).                          
001490         10  AMS-API-ZP4-G                 PIC X(001).                          
001500         10  AMS-API-ZP4-H                 PIC X(001).                          
001510         10  AMS-API-ZP4-I                 PIC X(001).                          
001520         10  AMS-API-ZP4-J                 PIC X(001).                          
001530         10  AMS-API-ZP4-K                 PIC X(001).                          
001540         10  AMS-API-ZP4-L                 PIC X(001).                          
001550         10  AMS-API-ZP4-M                 PIC X(001).                          
001560         10  AMS-API-ZP4-N                 PIC X(001).                          
001570         10  AMS-API-ZP4-O                 PIC X(001).                          
001580         10  AMS-API-ZP4-P                 PIC X(001).                          
001590         10  AMS-API-ZP4-Q                 PIC X(001).                          
001600         10  AMS-API-ZP4-R                 PIC X(001).                          
001610         10  AMS-API-ZP4-S                 PIC X(001).                          
001620*        multiple caused by magnet rule                                         
001630         10  AMS-API-ZP4-T                 PIC X(001).                          
001640         10  AMS-API-ZP4-U                 PIC X(001).                          
001650         10  AMS-API-ZP4-V                 PIC X(001).                          
001660         10  AMS-API-ZP4-W                 PIC X(001).                          
001670         10  AMS-API-ZP4-X                 PIC X(001).                          
001680         10  AMS-API-ZP4-Y                 PIC X(001).                          
001690         10  AMS-API-ZP4-Z                 PIC X(001).                          
001700         10  AMS-API-Z4P-RSVD3             PIC X(006).                          
001710     05  AMS-API-Z4P-ADDR-REC-STACK.                                            
001720         10  AMS-API-Z4P-STACK             OCCURS 10 TIMES                      
001730                                           PIC X(203).
001740     05  AMS-API-Z4P-RSVD4                 PIC X(194).                          
The "15 FILLER PIC X(001)" lines (000120, 000150, etc.) are needed for C++'s char array null terminator (achieving the same functionality as described in the comment line, NOTE: Only fields containing +1 in the length are null terminated.).

Compiler Options

C++ is case sensitive, and Fujitsu COBOL changes lower case into upper case by default.   When compiling a Fujitsu COBOL routine calling a C++ function, a compiler option (NOALPHAL) to over ride the upper case default must be specified, as shown in the two screenshots below:

test program compiler options details

The screenshot below shows all of the needed compiler options for the main program AMSTEST.COB:

test program compiler options summary

The MAIN compiler option simply specifies AMSTEST is a main program; DLOAD compiler option enables dynamic subprogram calling.

Linker Options

When linking, in addition to specifying the COBOL object file(s), the .DLL's import library (same name as the .DLL file but with a .LIB extension) should also be linked in.   For the AMS API, the library is ZIP4_W32.LIB.   See the below screenshot for an example:

test program linker options

And lastly, the .DLL's entry points must be defined within the Run-Time Environment Initialization File COBOL85.CBR.   For the AMSTEST example, ZIP4_W32.DLL's entry points are defined in COBOL85.CBR's entry information section, as shown below (the lines after [AMSTEST.ENTRY]; only the entry points actually being used are listed); these take the form of subprogram-name=dll-name:

When doing a Google Search for "COBOL AMS API" you may find several references for Google Docs with the same
terms and even graphics used in my Fujitsu COBOL web pages.   THE Google Docs ARE NOT MINE.   They may have links for
downloadable executable files which may or may not contain malware, adware, or other undesirable features.   Example addresses are:

Exercise Caution

Any and all © copyrights, ™ trademarks, and/or other intellectual properties (IP) mentioned here are the property of their respective owners.
No infringement is intended.

Feel free to 'cut and paste' any of the above COBOL code into your project (without violating any intellectual property rights); please give credit (same idea as Copyleft).

1 AMS API - RIBBS - USPS National Customer Support Center
2legal notice - the Fujitsu COBOL 3.0 compiler was freely available to students; unfortunately, it no longer is.
I used this compiler version only to determine if it was possible, prior to spending big bucks on an industrial grade compiler, to develop CASS certifiable commericial software using this approach.  NOTE - Later versions of Fujitsu COBOL may be better equiped for calling C++ functions.
3Initially, due to confusion in the Fujitsu COBOL documentation, I made the mistake of calling the AMS API '_stdcall' function using the "WITH C LINKAGE" clause in the COBOL call statement.   While this works, it may cause an invalid page fault.

Free web hosting provided by:
Award Space Web Hosting X10hosting Free Web Hosting. Hostinger Free Web Hosting. , &  GigaRocket Web Hosting

>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads