In the previous example you created the platform function object manually. You can also use the file parser to create pool dictionaries of function prototypes. You do this by sending the platformFunctions: message to an object table. This method takes the library name where the functions reside as input and returns a dictionary containing the function prototypes.
To parse the C sample header and create the platform function dictionary for the header file's contents, type the following code in a workspace, select it, and execute it.
"Parse the C header file creating a pool dictionary for constants and a pool dictionary for function prototypes" | anObjectTable CATMConstants CATMPrototypes | anObjectTable := AbtCLangParser parseFile: 'catm.h'. AbtRecordGenerator new generateAllFieldsFrom: (anObjectTable dataStructures at: 'ATM_CUSTOMER' asSmalltalkGlobalIdentifier) inClass: SampleCATMStruct. CATMConstants := anObjectTable constants. Smalltalk at: #SampleCATMConstants put: CATMConstants. CATMPrototypes := anObjectTable platformFunctions: 'catm'. Smalltalk at: #SampleCATMPrototypes put: CATMPrototypes
CATMPrototypes : = anObjectTable make16Bit platformFunctions: 'catm'. Smalltalk at: #SampleCATMPrototypes put: CATMPrototypes
Add the following method to your application to call the function using the prototype pool dictionary you just created:
invokeCATMUsingPrototype "This method calls the C ATM function in the CATM DLL, The method assumes the record wrapper has already been created and that the constants and function prototypes in the CATM sample have been placed in pool dictionaries" | atmStruct platformFunction | atmStruct := SampleCATMStruct new. atmStruct pinNumber: '12345'. platformFunction := Atm. platformFunction coroutineCallWithArray: (Array with: AtmQuery with: (atmStruct abtAsExternalPassedPointer)) threadKey: nil. Transcript show: (atmStruct firstName); cr; show: (atmStruct lastName); cr; show: (atmStruct checkingBalance); cr.
Note the expression atmStruct abtAsExternalPassedPointer in the example above. The abtAsExternalPassedPointer method causes the second parameter to be passed as a pointer regardless of its type in the platform function.
To test your new method, type the following on the System Transcript window, select it, and run it:
MjkStExtFunc new invokeCATMUsingPrototype
You should see the following in your System Transcript window:
John Smith 7890.03
To parse the COBOL copybook file and create the platform function dictionary for it, type the following code in a workspace, select it, and run it.
"Parse the COBOL program file creating a pool dictionary for constants and a pool dictionary for function prototypes" | anObjectTable COBOLATMConstants COBOLATMPrototypes | anObjectTable := AbtCOBOLLangParser parseFile: 'atm.cbl'. AbtRecordGenerator new generateAllFieldsFrom: (anObjectTable cobol01s at: 'ATM-CUSTOMER' asSmalltalkGlobalIdentifier) inClass: SampleCOBOLATMStruct. COBOLATMConstants := anObjectTable constants. Smalltalk at: #SampleCOBOLATMConstants put: COBOLATMConstants. COBOLATMPrototypes := (anObjectTable platformFunctions: 'ATM') make16Bit. Smalltalk at: #SampleCOBOLATMPrototypes put: COBOLATMPrototypes
Add the following method to your application to call the function using the prototype pool dictionary you just created:
invokeCOBOLATMUsingPrototype "This method calls the COBOL ATM function in the ATM DLL, The method assumes the record wrapper has already been created and that the constants and function prototypes in the ATM sample have been placed in pool dictionaries" | atmStruct platformFunction | atmStruct := SampleCOBOLATMStruct new. atmStruct pinNumber: '12345'. platformFunction := Atm. platformFunction coroutineCallWithArray: (Array with: AtmQuery with: (atmStruct abtAsExternalPassedPointer)) threadKey: nil. Transcript show: (atmStruct firstName); cr; show: (atmStruct lastName); cr; show: (atmStruct checkingBalance); cr.
Note the expression atmStruct abtAsExternalPassedPointer in the example above. The parser builds the prototype dictionary using struct for the second parameter instead of using a pointer. The abtAsExternalPassedPointer method causes the second parameter to be passed as a pointer regardless of its type in the platform function.
To test your new method, type the following un the System Transcript window, select it, and run it:
MjkStExtFunc new invokeCOBOLATMUsingPrototype
You should see the following in your System Transcript window:
John Smith 7890.03