Writing a data-conversion exit for WebSphere MQ on UNIX systems and Compaq OpenVMS Alpha

For SINIX and DC/OSx, data-conversion exits must not use DCE.

Follow these steps:

  1. Name your message format. The name must fit in the Format field of the MQMD, and be in uppercase, for example, MYFORMAT. The Format name should not have leading blanks. Trailing blanks are ignored. The object's name must have no more than eight non-blank characters because the Format is only eight characters long. Remember to use this name each time you send a message.
  2. Create a structure to represent your message. See Valid syntax for an example.
  3. Run this structure through the crtmqcvx command to create a code fragment for your data-conversion exit.

    The functions generated by the crtmqcvx command use macros which are written assuming that all structures are packed; they should be amended if this is not the case.

  4. Take a copy of the supplied skeleton source file renaming it to the name of your message format that you decided on in step 1 (that is, MYFORMAT.C).

    On WebSphere MQ for AIX, Compaq Tru64 UNIX, HP-UX, Linux, and Solaris the skeleton source file is called amqsvfc0.c. On MQSeries for AT&T GIS UNIX, Compaq OpenVMS Alpha, and SINIX and DC/OSx the skeleton source file is called amqsvfcx.c.

  5. With WebSphere MQ for AIX, a skeleton export file called amqsvfcx.exp is also supplied. Copy this file, renaming it to MYFORMAT.EXP.
  6. The skeleton includes a sample header file amqsvmha.h in the directory /usr/mqm/inc (on AIX) or /opt/mqm/inc (on other UNIX systems). Make sure that your include path points to this directory to pick up this file.

    The amqsvmha.h file contains macros that are used by the code generated by the crtmqcvx command. If the structure to be converted contains character data, then these macros call MQXCNVC.

  7. Find the following comment boxes in the source file and insert code as described:
    1. Towards the bottom of the source file, a comment box starts with:
        /* Insert the functions produced by the data-conversion exit */
      

      Here, insert the code fragment generated in step 3.

    2. Near the middle of the source file, a comment box starts with:
        /* Insert calls to the code fragments to convert the format's */
      

      This is followed by a commented-out call to the function ConverttagSTRUCT.

      Change the name of the function to the name of the function you added in step 7a above. Remove the comment characters to activate the function. If there are several functions, create calls for each of them.

    3. Near the top of the source file, a comment box starts with:
        /* Insert the function prototypes for the functions produced by */
      

      Here, insert the function prototype statements for the functions added in step 5a above.

  8. Resolve this call by linking the routine with the library libmqm. For threaded programs, the routine must be linked with the library libmqm_r (AIX and HP-UX only).
  9. Compile your exit as a shared library, using MQStart as the entry point. To do this, see Compiling data-conversion exits on UNIX, or Compiling data-conversion exits on Compaq OpenVMS Alpha.
  10. Place the output in the default system directory, /var/mqm/exits, to ensure that it can be loaded when required. The path used to look for the data-conversion exits is given in the qm.ini file. This path can be set for each queue manager and the exit is only looked for in that path or paths.

Notes:

  1. If crtmqcvx uses packed structures, all WebSphere MQ applications must be compiled in this way.

  2. Data-conversion exit programs must be re-entrant.

  3. MQXCNVC is the only MQI call that may be issued from a data-conversion exit.

UNIX environment

There are two environments to consider: non threaded and threaded.

Non-threaded environment

The loadable object must have its name in upper case, for example MYFORMAT. The libmqm library should be used to resolve the calls to MQXCNVC.

Threaded environment

In addition to creating the data-conversion exit for the basic environment, another is required in the threaded environment. This loadable object must be followed by _r (on AIX, HP-UX, Linux, and Tru64 V4.0) and _d (on Solaris) to indicate that it is a DCE-threaded version. The libmqm_r and lmqmcs_d libraries should be used to resolve the calls to MQXCNVC. Note that both loadable objects (non-threaded and threaded) are required for a threading environment.

If you are running MQI clients, all data conversion is performed by the proxy running on the machine to which the client is attached. This means that any data conversion exits are run on the server, in the environment of the proxy, and not as part of the client application.

For most platforms, the proxy/responder program is a threaded program. Consequently, the data conversion exit must be compiled with appropriate options to run in this threaded environment. Whether or not the client application is threaded is irrelevant.

On the WebSphere MQ V5 for UNIX systems, the proxy is threaded. The model of threads used depends on whether the DCE option has been installed.

Note:
If the data-conversion exits are in a mixed non-threaded and threaded environment, the calling environment is detected and the appropriate object loaded. The shared object should be placed in /var/mqm/exits to ensure it can be loaded when required.

Compiling data-conversion exits on Compaq OpenVMS Alpha

The names of the routines which are called by the data-conversion exit must be made universal.

  $ CC /INCLUDE_DIRECTORY=MQS_INCLUDE AMQSVFCX.C
  $ LINK /SYS$SHARE:[SYSLIB]MYFORMAT AMQSVFCX.OBJ,MYFORMAT/OPTIONS

The contents of MYFORMAT.OPT vary depending on which platform you are working on:

On Alpha:

  SYS$SHARE:MQM/SHAREABLE
  SYS$SHARE:MQMCS/SHAREABLE
  SYMBOL_VECTOR=(MQSTART=PROCEDURE)

On VAX:

  SYS$SHARE:MQM/SHAREABLE
  SYS$SHARE:MQMCS/SHAREABLE
  UNIVERSAL=MQSTART

If you are using threaded applications linked with the pthread library, you must also build a second copy of the data-conversion exit with the thread options and libraries:

  $ CC /INCLUDE_DIRECTORY=MQS_INCLUDE AMQSVFCX.C
  $ LINK /SYS$SHARE:[SYSLIB]MYFORMAT AMQSVFCX.OBJ,MYFORMAT/OPTIONS

Again, the contents of MYFORMAT.OPT vary depending on which platform you are working on:

On Alpha:

  SYS$SHARE:MQM_R/SHAREABLE
  SYS$SHARE:MQMCS_R/SHAREABLE
  SYS$SHARE:CMA$OPEN_RTL.EXE/SHAREABLE
  SYMBOL_VECTOR-(MQSTART=PROCEDURE)

On VAX:

  SYS$SHARE:MQM_R/SHAREABLE
  SYS$SHARE:MQMCS_R/SHAREABLE
  SYS$SHARE:CMA$OPEN_RTL.EXE/SHAREABLE
  UNIVERSAL=MQSTART

Compiling data-conversion exits on UNIX

The following sections give examples of how to compile a data conversion exit on the UNIX platforms.

On all platforms, the entry point to the module is MQStart.

On AIX 4.3

  $ cc -c -I/usr/mqm/inc MYFORMAT.C
  $ ld MYFORMAT.o -e MQStart -o MYFORMAT -bM:SRE -H512 -T512 -bE:MYFORMAT.EXP -lmqm -lc
  $ cp MYFORMAT /var/mqm/exits

You must build conversion exits for the threaded environment using the draft 10 Posix threads interface, which is the AIX 4.3 default.

  $ xlc_r -c -I/usr/mqm/inc MYFORMAT.C
  $ ld MYFORMAT.o -eMQStart -o MYFORMAT_r -bm:SRE -H512 -T512 -bE:MYFORMAT.EXP \
  -lmqm_r -lpthreads_compat -lpthreads -lc_r
  $ cp MYFORMAT_r /var/mqm/exits

On AT&T GIS UNIX

  $ cc -c -K PIC -I/opt/mqm/inc MYFORMAT.C
  $ ld -G MYFORMAT.O -o MYFORMAT
  $ cp MYFORMAT /opt/mqm/lib

On Compaq Tru64 UNIX Version 4.0

This example shows how to compile a data-conversion exit program in a nonthreaded environment:

$ cc -std1 -c -I /opt/mqm/inc myformat.c
$ cc -std1 -shared -o myformat myformat.o -L /opt/mqm/lib -lmqm -e MQStart -lc
$ cp myformat /var/mqm/exits

This example shows how to compile a data-conversion exit program in a threaded environment:

$ cc -std1 -c -I /opt/mqm/inc myformat.c
$ cc -std1 -shared -pthread -o myformat_r myformat.o -L /opt/mqm/lib \
  -lmqm_r -e MQStart -lc
$ cp myformat /var/mqm/exits

On Compaq Tru64 UNIX Version 5.0

This example shows how to compile a data-conversion exit program:

$ cc -std1 -c -I /opt/mqm/inc myformat.c
$ cc -std1 -shared -pthread -o myformat myformat.o -L /opt/mqm/lib \
  -lmqm -e MQStart -lc
$ cp myformat /var/mqm/exits

On HP-UX Version 11.00

  $ CC -c -Aa +z -I/opt/mqm/inc MYFORMAT.C
  $ ld -b MYFORMAT.o -o MYFORMAT -L /opt/mqm/lib -lmqm +IMQStart
  $ cp MYFORMAT /var/mqm/exits

If you are using threaded applications linked with the POSIX Draft 10 pthreads library, or you are running client applications, you must build the conversion exit for Draft 10 threads.

  $ CC -c -Aa +z -I/opt/mqm/inc MYFORMAT.C
  $ ld -b MYFORMAT.o -o MYFORMAT_r -L/opt/mqm/lib -lmqm_r -lpthread -lc
  +IMQStart
  $ cp MYFORMAT_r /var/mqm/exits

If you are using threaded applications linked with the POSIX Draft 4 (DCE) pthreads library, or you are running client applications, you must build the conversion exit for Draft 4 threads.

  $ CC -c -Aa +z -I/opt/mqm/inc -D_PTHREADS_DRAFT4 MYFORMAT.C
  $ ld -b MYFORMAT.o -o MYFORMAT_d -L/opt/mqm/lib -lmqm_d -ldr -lcma -lc
  +IMQStart
  $ cp MYFORMAT_d /var/mqm/exits

On Linux

To compile a user exit program for a nonthreaded environment use:

  $ gcc -c -I/opt/mqm/inc MYFORMAT.C
  $ gcc -o MYFORMAT -L/opt/mqm/lib  \
                      -lmqm -shared MYFORMAT.o

For a multithreaded environment, you must build a second copy of the conversion exit. Use:

  $ gcc -c -I/opt/mqm/inc MYFORMAT.C
  $ gcc -o MYFORMAT -L/opt/mqm/lib  \
                      -lpthread -lmqm_r -shared MYFORMAT.o

On SINIX

  $ cc -c -K PIC -I/opt/mqm/inc -lmproc -lext MYFORMAT.C
  $ ld -G MYFORMAT.O  -o MYFORMAT
  $ cp MYFORMAT /opt/mqm/lib

On DC/OSx

  $ cc -c -K PIC -I/opt/mqm/inc -liconv -lmproc -lext MYFORMAT.C
  $ ld -G MYFORMAT.O  -o MYFORMAT
  $ cp MYFORMAT /opt/mqm/lib

On Solaris

If your application uses no threading calls or Posix V10 threading calls:

  cc -c -KPIC -I/opt/mqm/inc MYFORMAT.C
 
  ld -G /opt/SUNWspro/SC4.0/lib/crt1.o \
  /opt/SUNWspro/SC4.0/lib/crti.o \
  /opt/SUNWspro/SC4.0/lib/crtn.o \
  /opt/SUNWspro/SC4.0/lib/values-xt.o \
  MYFORMAT.o -o MYFORMAT -lmqm -lthread -lsocket -lc -lnsl -ldl
 
  cp MYFORMAT /var/mqm/exits

If your application requires DCE threading (for example, if it is a CICS application):

  cc -c -KPIC -I/opt/mqm/inc MYFORMAT.C
 
  ld -G /opt/SUNWspro/SC4.0/lib/crt1.o \
  /opt/SUNWspro/SC4.0/lib/crti.o \
  /opt/SUNWspro/SC4.0/lib/crtn.o \
  /opt/SUNWspro/SC4.0/lib/values-xt.o \
  MYFORMAT.o -o MYFORMAT_d -ldce -lnsl -lthread -lm -lsocket \
  -lmqmcs_d -lmqm -lc -ldl
 
  cp MYFORMAT /var/mqm/exits
Note:
The SC4.0 directory name varies depending on the release of compiler.

If you want to run applications using both the Posix V10-threaded and the DCE-threaded variants on a single queue manager:

  1. Build a Posix V10 type of data-conversion exit. Name it MYFORMAT and place it in the appropriate exit directory.
  2. Build a DCE-threaded type of data-conversion exit. Name it MYFORMAT_d and place it in the appropriate exit directory.

Two object files are generated; one of which loads the MYFORMAT data-conversion exit, and the other of which loads the MYFORMAT_d data-conversion exit.



© IBM Corporation 1993, 2002. All Rights Reserved