The Distributed Program APIs

Embed Size (px)

Citation preview

  • 7/27/2019 The Distributed Program APIs

    1/16

    The Distributed Program APIs

    Contributed by Craig PelkieFriday, 31 March 1995Last Updated Friday, 31 March 1995

    With no fanfare whatsoever, IBM introduced a major new API set for the Windows client of Client Access/400. This set,collectively known as the Distributed Program APIs, is available with the System Object Access function. Simply stated,the APIs let you develop programs on the PC that can directly call programs on the AS/400, passing and receivingparameter values.

    This is a radical innovation, and potentially will help you develop client/ server programs much more quickly than usingother APIs. Because you can directly call an AS/400 program, you dont need to code special communications code, aswith the APPC APIs, or include data queue handling when using the data queue APIs. In fact, if you have AS/400functions already split out into subprogramsfor example, a tax calculation routine that is in a separate programyou shouldbe able to call those programs directly from your PC program. The Distributed Program APIs can help you createclient/server programs more quickly than other methods because you can use the AS/400 programs that you alreadyhave.

    How to Get the APIs

    You get the Windows DLL that provides the API functions when you install System Object Access (SOA). You can order

    SOA as a PTF package (SF21273 for licensed program 5763-XC1), or install SOA from the Client Access/400 refreshthat is scheduled for release soon. If you order the PTF, you need to specify DELIVERY(*ANY). The PTF package will besent to you on tape because the package is too large to be sent over ECS. (See the May/June 1995 issue of PCSE for areview of other functions in SOA, System Object Access - Application or API?)

    When you install SOA, a subdirectory called SOASPGMS is created in your CAWIN directory. The SOASPGMS directorycontains sample programs and source

    code for running the SOA programs. The file that you want to look at is EHNDPW.H, the C header file for the DistributedProgram-Windows APIs. The header file contains some documentation for the APIs, constants used with the APIs, andfunction declarations for each of the APIs.

    In addition to the header file, file EHNDPW.DLL is installed in the CAWIN directory. The DLL file contains the executablecode for each of the APIs. The DLL can be used with any PC language that supports the C calling convention. The APIs

    in EHNDPW.DLL can only be used by Windows programs.

    API Functions Provided

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    2/16

    There are 25 user-accessible functions within EHNDPW.DLL. These functions are divided into three groups.

    System Functions are used to create a connection between the PC program and the AS/400. When you use the system

    functions, you start a server job on the AS/400 that processes your program call requests. You also end the server jobusing a system function API.

    The Program Functions group contains APIs to define the program that will be called, work with parameters for theprogram, call the program, and get information about the program and parameters.

    Finally, the Message Functions group helps you get messages and information about messages that are sent as a resultof errors when calling the program.

    As with any API set, it makes sense to learn about the APIs by looking at how theyre used, rather than by proceedingthrough the APIs alphabetically. There is a specific sequence that youll need to use when calling a program with theAPIs. Youll also find that you only need to use a subset of the APIs to get started.

    Getting Started with the APIs

    To get started with the APIs, youll first want to print file EHNDPW.H, the C header file. Even if you plan to use a PC

    language other than C, youll need to examine this file to learn about the APIs, the parameters used on the functions, andthe return code values that you might encounter. Later in this article, Ill tell you how to get an equivalent file of functiondeclarations that you can use with Visual Basic.

    EHNDPW.H starts with notes about how the APIs are used. If you are accustomed to working with PC languages, theconcepts and program flow will probably be easy to grasp. However, if most of your experience is as an RPGprogrammer, you might find it difficult, at first, to understand how the APIs are used. With an RPG program, youcustomarily include a CALL statement, followed by PARM statements. The Distributed Program APIs define theparameters first, then call the program. Ill explain this in more detail later.

    After the initial documentation, EHNDPW.H continues with definitions for constants. The first set of constants is used todefine the maximum number of parameters, and the parameter types. You can call an AS/400 with up to 25 parameters.

    Parameter types can be defined as input, output, or input/output. These types provide options that are different from theway an AS/400 programmer customarily uses parameters. In an RPG, COBOL, or CL program, all parameters areinput/output, as values can be passed and returned through any parameter (i.e., if you call an AS/400 program fromanother AS/400 program, the called program can change a parameter, and the change is reflected back to the caller).

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    3/16

    The input and output parameter types are used extensively with the APIs themselves. An input parameter is passed fromthe calling program to the called program. Any changes to the parameter are not returned to the caller. An outputparameter is in the parameter list of the calling program; however, any value that you set in the calling program is notpassed to the called program. The called program can change the value of the output parameter. The changed value isavailable to the calling program upon return from the called program.

    To call existing AS/400 programs, you might want to consider defining the parameters as input/output, as that providesthe same type of parameter usage available with AS/400 languages. Youll need to examine existing code carefully to seeif you can define parameters as simple input or output parameters.

    The next set of constants in EHNDPW.H is used to define message types. These constants are used with the MessageFunctions API group. For example, you can test a message to determine if it is a completion, diagnostic, notify, or escapemessage.

    The final set of constants define return codes from the API functions. These are in four general groups: the OK returncode, meaning that the API functioned correctly; communications return codes (e.g., no connection to system); programerrors (e.g., program not found, too many/ too few parameters); and environment errors (e.g., invalid window, system, orprogram handle). As with any API, you should, at a minimum, check for the OK return code. If the return code is not OK,you can then go to a generic error handling routine, or you can branch to specific error handling depending on the type ofreturn code.

    The Function Declarations

    After the constants, EHNDPW.H begins the function declarations. The declarations are listed by function group (i.e.,system, program, message), and roughly in order by usage within the groups.

    Each API function declaration starts with a synopsis that includes the name of the API, a brief description of it, then a listof the parameters used with the API. Although the synopsis includes a reference for return codes, none of the APIscurrently have any documented return codes. You should be able to examine the return code constants and determinewhich ones will apply to an API. You can also test each API individually to discover the return codes that you mightencounter (e.g., call a nonexistent program to discover the return code that you get in that situation).

    The function declarations are standard C syntax and formatting. Windows conventions are used for the data type andvariable names.

    All of the Distributed Program functions start with the character string EHNDP_. The second part of the function name isdescriptive of the function. For example, the EHNDP_StartSys API is used to start the conversation with the AS/400.

    If you work with C, you should find the function declarations to be straightforward. But even if youre unfamiliar with C, ordont use C as your primary programming language, you should spend some time reading through the declarations. Youllwant to know the functions that are available, their names, and the parameters used with each function.

    The Distributed Program API Tester Program

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    4/16

    I created a test program in Visual Basic to learn about the Distributed Program APIs. Figure 1 shows the dialog that ispresented when the program is run. The program uses six command buttons to run Distributed Program functions. TheVisual Basic

    program calls an AS/400 CL program, passing parameters to it. The CL program sends a message to the QSYSOPRmessage queue, displaying the parameters. The CL program finishes by moving a value into a parameter. The returnvalue is obtained with a Distributed Program API and placed into the message list box shown in the figure. The code forthese programs is too long to include with this article, but you can get it with the Visual Basic function declaration file.Even without the code, we can examine the flow of the Tester program, which I feel is representative of the flow that youwould use for production programs. The Tester demonstrates the initialization and cleanup work youll need to do, andalso how to define parameters, put values into them, call the AS/400 program, and extract the value for returned

    parameters.

    Before stepping through the details of the program, we need to get an overview of processing flow, as it relates to usingthe Distributed Program APIs.

    Sequence and Flow of the APIs

    I mentioned earlier that using the Distributed Program APIs is not quite the same as the AS/400 CALL/PARM construct.There are several additional steps that you need to take before issuing the program call. You need those additional stepsbecause you must create the proper environment for the program call. You then need to provide details about each ofthe parameters youre going to use. After actually calling the program, you retrieve the parameters that contain returnvalues. When youre finished, you close the environment that you created for the APIs.

    Before you can use the Distributed Program APIs, you need a router connection to the AS/400 where the program thatyou want to call is located. Your first step with the Distributed Program APIs is to start a connection to the system. Youthen create a program, which means that you identify the program youre going to call. After creating the program, youcan add up to 25 parameters to it. As with any AS/400 program, the parameters must match those on the called program.

    At that point, you can call the AS/400 program. Assuming that youve correctly defined the parameters and have aworking connection, the AS/400 program will run. The called program must be batch oriented; you cannot call an AS/400program that uses display file I/O.

    When the AS/400 program returns or ends, you then call Distributed Program APIs to retrieve the parameter values.Unlike standard AS/400 programs, where values for all of the parameters are available to the calling program when thecalled program returns, you specifically have to retrieve the value from each parameter in which youre interested.

    At this point, you can call the same or another program. You already have the connection environment, so you dont needto start the system again. If youre calling a different program, you need to create the program and add parameters to it. Ifyoure recalling a program that youve already created and added parameters to, you can use an API to set the value ofthe parameters for a subsequent call.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    5/16

    When youre done working with the AS/400 programs, you delete the program, which removes it from your PCenvironment. Finally, you stop the system, which means that your connection with the AS/400 is dropped (not the router,just the Distributed Program connection to the server program).

    At any point during your calling sequence, you may need to use the APIs that obtain information about the environment.After calling an API, you will need to check the return code. If the call was unsuccessful, you may need to call themessage handling

    APIs to retrieve the AS/400 error messages. The message handling APIs provide functions equivalent to the programmessage queue handling operations on the AS/400.

    Ill explain what happens when you click each of the command buttons on the Tester. When you obtain the source codeand run the program, youll find it useful to step through the program and set breakpoints.

    The Start System Function

    Before you can call an AS/400 program with the Distributed Program API, you have to start a connection to the AS/400.This connection is between your PC program and an AS/400 server job. This connection presumes that you have anactive router connection to the AS/400.

    If you attempt to start the program connection without having an active router session, the start attempt fails.

    You start the program connection with the EHNDP_StartSys (StartSys) API. Figure 2 shows the details of this API.StartSys uses four parameters. The first, hWnd, is the handle to the window that the program is associated with. This is

    standard Windows programming practice. hWnd is the first parameter of all of the Distributed Programming APIs, so Iwont describe it again from this point on.

    The second parameter is the name of the system with which you want to start the connection. This is one of the systemsto which you have a router connection. As with other Client Access APIs, you can pass a null value for this parameter, inwhich case the default system is used.

    The third parameter is the application name. This is supposed to be a unique identifier for the application youre starting.A null value is allowed for this parameter. The application name is not used in any of the other Distributed Program APIs,so its purpose is unclear.

    The last parameter is a return value, the handle to the system. This is a very important value, as it is used with other

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    6/16

    Distributed Program APIs to point the APIs to the correct system. For example, if you start connections to two systemswithin the same PC program, you need to use StartSys for each system. Youll get a unique handle for each system,which then identifies that system. As with any handle, you must never alter its value. You just use the value that ispassed back from the API. The value has no meaning as far as your application is concerned; it is used internally by theAPIs.

    When you use StartSys, two jobs are started in the QCMN subsystem. The first job starts program QLZPSERV. I couldntdetermine the functions performed by this job, in relation to the Distributed Program APIs. The second QCMN job startsprogram QIWS/QZRCSRVR. This program is the actual server processor, which handles Distributed Program requestsfrom your PC program. This job uses ICF file QIWS/QCZRCICF to communicate with the PC. Examining this job showsthat APPC is being used to communicate from the PC program to the AS/400 program. However, were insulated from thelow-level APPC programming required for communications between the two machines. This is one of the mainadvantages of the Distributed Program APIs.

    If you used a null value for the system name on StartSys, you can find out the name of the system used with theEHNDP_GetSysName (GetSysName) API. The API is described in Figure 3. If you explicitly passed a system name,there would be no point to call this API because youd already know the name of the system. But if youre creating general-

    purpose programs that might run with different AS/400s, you might need to use the null system name value on StartSys,then use GetSysName to get the default

    name. You could also use EHNAPPC_GetDefaultSystem from the APPC API, but GetSysName ensures that you get thesystem name that applies to the StartSys API usage.

    GetSysName uses three parameters. The second is the handle to the system that was returned from StartSys. The thirdis the name of the system that the connection was started to.

    Figure 1 shows the result of clicking the Start System command button. The message list box at the top of the figurecontains messages that I formatted after calling the APIs. After calling each API, I check for a return code ofEHNDP_OK, meaning that the API completed successfully. If the return code is not OK, I go to an error messageformatting routine. For some APIs, such as the StartSys API, I include additional information on normal completion. Inthis example, Im displaying the hex value of the system handle returned by StartSys. I include a separator line between

    each API, as shown in the figure. After clicking each command button, you can review the additional messages byscrolling through the message list box. I cant show you the entire sequence of messages in the list box, so I wontdescribe them any more in this article. Just be aware of the function when you run the sample program.

    The Create Program Function

    Contrary to what you make think from its name, the EHNDP_CreatePgm (CreatePgm) API does not create a program onthe AS/400 in the way that a CRTxxxPGM command does. Instead, the CreatePgm API creates a program object in yourPC memory. That object is used to identify the actual program that you want to call on the AS/400, and serves as aconnection between your PC and the actual AS/400 program. Figure 4 shows the parameters used with CreatePgm.

    If most of your programming experience is in the AS/400 environment, youll want to take the time to be clear on how the

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    7/16

    terminology used with this API differs from the AS/400 terminology. The API uses the verb create and the noun object,which AS/400 programmers instinctively associate with a program object being created from source.

    As you can see from Figure 4, what youre really creating with this API is a handle to a named program. This is all done inthe PC memory. When you run this API, there is no communication flow to the AS/400. The API does not verify that yousupplied a valid library and program name. If you used incorrect values (e.g., you specified a program name that doesnt

    exist), you wont find out about it until you actually call the program.

    You need to run this API to get the handle assignment. After getting the handle to the program, youll need to addparameters to the program using the handle. Finally, you can call the program.

    I havent yet experimented with special or NULL values for the library name parameter. The QCMN communications entrythat handles the program evoke request when the program is called specifies a default user value of *SYS. The userprofile used to start the router is associated with the server job that processes the request, so the library list for the useris available to the job. I presume that special values like *LIBL are supported for the library name parameter on this API.

    After calling the CreatePgm API, you have a handle to the system where the program is located, and a handle to theprogram object that youre going to call. That takes care of establishing the environment for the program. You now needto add parameters to the program before calling it.

    The Add Parameter Function

    Unlike the AS/400 CALL/PARM construct, you define your parameters before issuing the call. You define parameterswith the EHNDP_AddParm (AddParm) API, shown in Figure 5.

    When you use AddParm, what youre really doing is reserving space in your PC memory. This space is simply asequence of 1 to n bytes. You specify how many bytes to reserve for the parameter. When you use AddParm, a pointer

    to that space is set, and the parameter count is incremented. The pointers and parameter count are associated with theprogram that youre going to call, by the program handle value that was returned in CreatePgm.

    AddParm uses a parameter to specify the type of parameter, which has nothing to do with the field characteristics (stringor numeric and length). The type of parameter is input, output, or input/output. If youre an AS/400 programmer, youllprobably be most comfortable defining all of the parameters as input/output, as that provides an equivalent to howAS/400 programs call each other. As you become more familiar with the Distributed Program APIs and processes, youmight want to refine your parameter type usage.

    This is actually a pretty interesting process, under the covers. The way this process works, it appears that there is amechanism within the AS/400 server to add parameters dynamically to a program call. This differs from the usual AS/400programming practice, where you hard-code the number of parameters into your AS/400 source programs. Now, forsure, the AS/400 has always had such a built-in parameter handling mechanism because it has to resolve the number ofparameters when one AS/400 program calls another. Here, we have access to this parameter list building process.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    8/16

    Unlike AS/400 programs, you dont specify the type of parameter, but only the length of the parameter. For characterstring fields, you can simply use the length of the string. For numeric fields, youll have to be careful to match theexpected parameter in the AS/400 program. For packed fields, which are the default in CL programs and RPG programsunless defined differently, you need to calculate the number of bytes required to hold the field and the sign half-byte. Forexample, if a CL program parameter variable is DEC(5,0), youll need a parameter length of 3 on the AddParm API (two

    and a half bytes used for the five digits, one-half byte for the sign). If the parameter is DEC(6,0), you need a parameterlength of 4.

    If youve defined the numeric field explicitly as zoned or binary, then you need to specify the number of bytes required tohold the field.

    In my testing, I found numeric parameters to be particularly troublesome. This is because of the parameter lengthconsideration, and also because the values need to be converted from ASCII to packed, zoned, or binary, then back,when returning to the PC program. The conversion functions are in the Data Transform API (EHNDT). They are not

    particularly easy to use in Visual Basic, as you need to work with pointers to the values. The sample program includes anexample of ASCII-to-Packed conversion.

    As with any call to an AS/400 program, you must supply the right number of parameters, and values for numericparameters must be valid. For example, if your AS/400 has three parameters, you cant just concatenate all of the valuesin your PC program and pass one parameter thats as long as all three. You need to pass three correspondingparameters. If you dont pass valid numeric values, youll get MCH-type error messages when your called program on theAS/400 references the parameter. Based on the experience I had with the Distributed Program APIs, youll want aprogram like Tester to experiment with parameter passing.

    The Call Program Function

    After defining your parameters, you use the EHNDP_CallPgm (CallPgm) API to actually call the AS/400 program fromyour PC program. Looking at the function definition in Figure 6, you can see that this API is almost anticlimactic. Thats

    because youve done all of the set-up work before issuing the call. The API simply references the handles of the systemand the program that were created earlier. The parameter list is from the AddParm API calls that you did before usingthis API.

    As with AS/400 program-to-program calls, this is where the action and the problems start. Youll run into the usualproblems, such as the program not being found, authority problems, incorrect parameters, and so on. Upon return to yourPC program, you absolutely must check the return code from the CallPgm API before you even think of using any otherDistributed Program APIs. If the return code is anything other than EHNDP_OK, you had a problem. You can use themessage function APIs to retrieve the messages sent from the AS/400, and possibly determine what the cause of thefailure was (chances are that the system operator will also get messages on the AS/400, and youll have a job log fromthe failed job to work with).

    The Distributed Program APIs include two APIs that relate to the call mode of the program. The default call mode issynchronous, meaning that while the called AS/400 program is processing, your PC program is locked. The

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    9/16

    EHNDP_SetCallMode API lets you set the call mode to asynchronous, meaning that you can call the AS/400 program,then resume your PC program while waiting for the called program to return. The EHNDP_GetCallMode API retrieves avalue that lets you determine the current mode being used.

    I didnt see any documentation about how this feature works, but I suspect that Windows call-back processing is used. Ifso, Visual Basic programs are limited to synchronous mode, unless third-party VBXs or custom controls that provide call-

    back support are obtained. I did not test the SetCallMode API; all of my tests were done with the default, synchronouscall mode.

    My feeling is that this should not present too much of a problem. If youre going to use existing AS/400 modules, chancesare that those modules are already working with interactive programs. In that case, when you call the module from anAS/400 program, you are, in effect, working in synchronous mode anyway. Your response time should be comparable toan AS/400-to-AS/400 program call, meaning that it should be tolerable, especially after the first call. If you find responsetime of synchronous calls to be an issue, and youre working with Visual Basic (no call-back support), you might need toconsider alternative methods of submitting work and then checking for a response, such as data queues.

    The Get Parm API

    At this point, you have all of the APIs you need to call an AS/400 program and pass parameters to it. Although useful,you probably also want to receive parameters back. To do that, youll need to use the EHNDP_GetParm (GetParm) API,shown in Figure 7.

    You need to call GetParm for every parameter for which you want to retrieve a value. Thats because you dont have aparameter list, as in an RPG program; you cant just refer to values. Even though you added the parameter earlier with

    the AddParm API, you need to use GetParm. Think about whats happening: the AS/400 program has returned, andwritten the parameter values out. You didnt directly call the AS/400 program; you used the server program on the AS/400as your intermediary.

    Because the server program doesnt have hard-coded knowledge of how many parameters youre working with, you have

    to request those parameters from the server with the GetParm API. When you use GetParm, the parameter values areretrieved from the server program and written to your PC memory, where you can then reference them.

    GetParm is tricky to use, especially in Visual Basic, because the returned parameter is a pointer to a pointer. Youll needto use either the EHNDT_MemCopy API or the Windows lstrcpy function to copy the returned parameter from thememory location indicated by the pointer to a buffer (string) that you can use in Visual Basic.

    Another consideration with GetParm is that you reference the parameter you want by relative order in the parameter list.You need to refer to the parameter by number because there are no field names associated with the returned parameterlist, as in an RPG program. The list is zero-based, meaning that the first parameter is identified as parameter zero, thesecond parameter in the list is identified as parameter one, and so on.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    10/16

    Another API that you might need to use is EHNDP_GetParmCount (GetParmCount), shown in Figure 8. This API returnsa value that indicates the number of parameters in the list. Using GetParmCount, you might be able to create a genericparameter retrieval routine in your PC program, looping through GetParm for the number of parameters fromGetParmCount. The alternative is simply hard-coding GetParm code for each parameter.

    After you retrieve the parameters that you can work with (in Visual Basic you have to move them to a buffer), youll need

    to do some additional work before you can use the value. For character string values, youll need to do an EBCDIC toASCII translation. For numeric parameters, youll need to use the appropriate Data Transform API to convert frompacked, zoned, or binary to an ASCII numeric value. This can be tedious and error-prone coding. Youll probably want torun some test cases, then create wrapper functions that you can simply include in your production programs.

    The Delete Program API

    When youre done calling the AS/400 program, you should call the EHNDP_DeletePgm (DeletePgm) API to remove theprogram object from your PC memory. Doing so will free up the memory for other purposes. The DeletePgm API does

    not delete the program object on the AS/400.

    Figure 9 shows the DeletePgm API parameters. After you call this API, you can no longer use the CallPgm API for thesame program handle. You would have to use CreatePgm again to create a new handle and program object.

    You can call DeletePgm at any point after creating the program handle. For example, if your application only needs tocall an AS/400 program once for initialization purposes, theres no point to keeping the program object constructs in PCmemory after the initialization.

    The Stop System API

    When youre done calling AS/400 programs from your PC program, youll want to call the EHNDP_StopSys (StopSys)API, shown in Figure 10. Calling this API terminates the conversation with the server program on the AS/400. If youneglect to call this API, the server program remains active.

    After calling this API, the handle to the system that was created in the StartSys API is no longer usable. If you want to

    call AS/400 programs again, you need to go through the entire process, starting with StartSys.

    If you started conversations to multiple systems, you need to run StopSys for each system. Conversely, you can useStopSys for one system, but continue to use active conversations to other systems.

    Other APIs

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    11/16

    In this article, I have not shown or described many other APIs. Figure 11 shows the names of those APIs and brieflydescribes them.

    In the Tester program, I use several of the Message Function APIs to retrieve error messages from the AS/400.

    Distributed Program Versus Other Techniques

    As exciting as the Distributed Program API suite is, you need to consider where it fits in with other Client Access/400APIs and techniques. It is true that this suite provides the equivalent function that AS/400 programmers have used foryears: the capability of calling one program from another, and passing parameters between the programs. However, thattechnique has always had built-in limitations.

    For example, say that you want to create a server program that youll call to read records from a file. You dont know howmany records each call will return; it could be from zero to many. Its tricky to write such a server, and fill up an arbitrarybuffer with records. I know; Ive created a system that uses such servers. In this case, it might be better to use an APPCor a CPI-C program, or a data queues program, to receive the file processing request, then fill a buffer that is external tothe program. For example, APPC and CPI-C send operations will fill a communications buffer that the system manages.With data queues, you simply write a data queue entry for each record. The system manages the buffer. Your receivingprogram has a far easier job because it can simply retrieve one entry at a time from the buffer or queue.

    On the other hand, you probably have a number of routines already coded that youve been using for years in yourproduction systems. If youve been careful to create stand-alone modules, you can probably call those modules from yourWindows programs. This will help you quickly develop a Windows equivalent to the AS/400 program because you dont

    have to recreate the logic that is available in the existing modules.

    There is no limitation on using any of these techniques exclusively in a program. You might find that you use both theData Queues and the Distributed Program APIs in the same program. The Distributed Program API is certainly awelcome addition, but it does not render the existing techniques obsolete.

    The Tester Program

    The Tester program, as illustrated in Figure 1 and described in this article, includes the Visual Basic code for the formand a Visual Basic equivalent of the EHNDPW.H file, in which I provide function declares for the Distributed ProgramAPIs.

    This code is available on the Midrange Computing BBS in the AS/400 file download area, or directly from me. The BBSnumber is listed on page 2 of this issue of PCSE.

    If you prefer, you can send your request for the code to me at the address shown below. Youll need to include a self-addressed, stamped envelope with 55 cents postage for U.S. addresses (foreign subscribers, please determine thecorrect postage and prestamp your envelope with U.S. postage). Youll also need to include one 3.5-inch

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    12/16

    blank, IBM-formatted diskette. Requests without postage or the diskette will not be processed.

    Acknowledgments

    I especially want to thank Mike Young and his developers at the IBM Rochester lab. Mike called me about some otherissues, and during our conversation, I mentioned that I was working with the Distributed Program APIs. At the time, Iencountered what I thought might be a bug in the DLL. The problem was with the EHNDP_GetParm API. Mike confirmedthe problem and sent an updated version of the DLL to me. He also indicated that this correction will be made availableas a PTF at some point. The version of EHNDPW.DLL that I have is dated 6/27/95. The version distributed with SOA is3/30/95. If you install the SOA code and have that version of the file, you will encounter the bug. I cannot provide theupdated version of the DLL, so you will have to monitor either the IBM PTF list (SF97310), or check future issues of

    PCSE for notification of the public availability of the fix.

    Finally, I want to thank Daniel Appleman of Desaware in San Jose, California. Daniel helped me with the code required toreference a parameter on the EHNDP_GetParm API. Daniel specializes in Visual Basic API programming. In addition tocreating tools for Visual Basic, he wrote the definitive book on accessing Windows DLLs from Visual Basic. Ive listed thebook title below. If youre going to work with Visual Basic and the Client Access/400 or PC Support APIs, you will find thisbook to be an outstanding resource.

    References

    Visual Basic Programmers Guide to the Windows API, Daniel Appleman, Ziff- Davis Press, 1993 (ISBN 1-56276-073-4).

    Tester Diskette Address Craig Pelkie PO Box 1473 Valley Center, CA 92082-1473

    Figure 1: The Distributed Program API Tester Dialog

    Purpose Start a conversation with an AS/400. If successful, a handle for the conversation is returned.

    Parameters

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    13/16

    hWnd Handle to the window. lpszSystemName ASCIIZ string containing the system name, or NULL for default system.lpszAppName ASCIIZ string of unique application identifier. Can by NULL. lphSystem Handle to the conversation for thesystem.

    Figure 2: The EHNDP_StartSys API

    Purpose Get the name of the system used when starting the connection with

    EHNDP_StartSys.

    Parameters

    hWnd Handle to the window. hSystem Handle to the system. This is from the lphSystem parameter on EHNDP_StartSys.lpszSystemName 9-character buffer where the name of the system

    will be written (8-character system name, 1 space for terminating NULL character).

    Figure 3: The EHNDP_GetSysName API

    Purpose Create a program object (handle to the program) for a given library and program name.

    Parameters

    hWnd Handle to the window. lpszProgramName ASCIIZ string containing the name of the AS/400

    program to be called. lpszLibraryName ASCIIZ string containing the name of the AS/400 library where the program islocated.lphProgram Handle to the program object.

    Figure 4: The EHNDP_CreatePgm API

    Purpose Add a parameter to the program identified by the program handle. Use this

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    14/16

    API for each parameter to be passed. Parameters are added to the program in the order that this API is called.

    Parameters

    hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm). uiType The type ofparameter. This can be EHNDP_INPUT, EHNDP_OUTPUT, or

    EHNDP_INOUT (see EHNDPW.H for definitions of those constants). ulLength The length of the parameter.lpParameter Pointer to the buffer where the parameter value is located for INPUT or

    INOUT parameter types; or pointer to buffer where parameter value will be returned for OUTPUT or INOUT parametertypes.

    Figure 5: The EHNDP_AddParm API

    Purpose Calls the program identified by the program handle. The return code indicates the success or failure of the call.

    Parameters

    hWnd Handle to the window. hSystem Handle to the system from EHNDP_StartSys. hProgram Handle to the programobject (from EHNDP_CreatePgm).

    Figure 6: The EHNDP_CallPgm API

    Purpose Retrieve the parameter identified by the index. You have to call this API for every parameter for which you wantto retrieve a value.

    Parameters

    hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm). uiIndex Number of theparameter to retrieve. Parameter count starts at 0. lpuiType Pointer to the type of parameter (EHNDP_INPUT,EHNDP_OUTPUT,

    EHNDP_INOUT). length The length of the parameter in bytes. lplpParameter Pointer to a pointer that indicates where theparameter value is written.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    15/16

    Figure 7: The EHNDP_GetParm API

    Purpose Get the number of parameters for the program identified by the program handle.

    ParametershWnd Handle to the window.hProgram Handle to the program object (from EHNDP_CreatePgm). lpusCount Unsigned integer containing the numberof parameters.

    Figure 8: The EHNDP_GetParmCount API

    Purpose Delete the program object (construct in PC memory) identified by the handle.

    Parameters

    hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm).

    Figure 9: The EHNDP_DeletePgm API

    Purpose Stop a conversation with the system identified by the handle.

    Parameters

    hWnd Handle to the window. hSystem Handle to the system that was created by the EHNDP_StartSys API.

    Figure 10: The EHNDP_StopSys API

    API Description

    EHNDP_GetPgmName Get the name of the program used on the EHNDP_CreatePgm API. EHNDP_GetLibName Getthe name of the library used on the EHNDP_CreatePgm API. EHNDP_SetParm Set the parameter value identified by theindex. Use this to change a parameter value, after using the EHNDP_AddParm API. EHNDP_SetPgmName Set thename of the program.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 04:36

  • 7/27/2019 The Distributed Program APIs

    16/16

    EHNDP_SetLibName Set the name of the library. EHNDP_GetMsgCount Get the number of messages returned by theAS/400. EHNDP_GetMsgId Get the message ID of the message returned from the AS/400. EHNDP_GetMsgType Getthe type of message returned from the AS/400. EHNDP_GetMsgLen Get the length of the message returned from theAS/400. EHNDP_GetMsgSev Get the message severity of the message returned from the AS/400. EHNDP_GetMsgFileGet the message file name and library for the message returned from the

    AS/400. EHNDP_GetMsgText Get the message text returned from the AS/400. EHNDP_GetSubstTextLen Get thelength of the substitution text for the message returned from the

    AS/400. EHNDP_GetSubstText Get the substitution text for the message returned from the AS/400.

    Figure 11: Other Distributed Program APIs

    MC Press Online