═══ 1. TrimDll Version 1.0 ═══ A utility to tailor your UICL distribution DLLs. This program follows more or less the hints given in IBM's 'VAC++ Open Class Library User's Guide', Chapter 27, 'Rebuilding the Open Class Library DLLs'. (I may use quotations from that book within my text). In addition, based on some personal experiences, a more specific step-by-step instruction is given. ═══ 1.1. What you can do with the program ═══ You can compose a new response file from one of the original IOC response files (CPPOOB3.RSP, CPPOOU3.RSP, CPPOOD3.RSP, CPPOOM3.RSP), create a new definition file from these with only the required exports, and link the selected object modules into a new DLL. This will reduce required space on your distribution media and the installed application. It can also result in faster load time for the application. ═══ 1.2. What you need to know ═══ Remember: You are not allowed to deliver the original runtime libraries when you distribute a program you wrote using IBM's CSet++ or VAC++. Instead, you must link it statically or rename the required DLL's and ship them as a whole. Both options will blow up your package, even if you used only some of the provided classes within that program. Another way is to rebuild the DLL's by removing classes not needed. This is always an annoying job, because you have to take care about not to remove too many object module names and to keep the required exports in sequence. It's here where this program could help. Using the UICL from VAC++ with dynamic linking, you are dealing with this libraries:  CPPOS30.DLL - always needed for single threads  CPPOM30.DLL - always needed for multi threads  CPPOOB3.DLL - the application support- and collection-classes  CPPOOU3.DLL - the the UI classes  CPPOOM3.DLL - the multimedia support (IMM*.OBJs)  CPPOOD3.DLL - the DDE support (IDDE*.OBJs) These recommendations are basically given for modifications, :  From CPPOOB3.RSP - remove all N*.OBJ if you never use I_NO_INLINES when compiling  From CPPOOU3.RSP - remove all ICNR*.OBJ if you do not use container controls - remove all IDM*.OBJ if you do not use direct manipulation or toolbar  For CPPOOM3.DLL and CPPOOD3.DLL - not needed if you never use multimedia and/or DDE classes This will already reduce the space needed. But there could be more to omit, and up to a certain complexity, it might be worth to play around to save some more 100k in size. ═══ 1.3. What you need before you start ═══ There are some files you need to prepare before you can rebuild the DLLs. ═══ 1.3.1. The distributed files you need ═══ Needed files that are shipped with the distribution package are the definition(.def) and the response(.rsp) files for the DLLs to modify and the GETOBJS command file to extract the object modules. They are installed in the \IBMCPP\IOCDLL directory. ═══ 1.3.2. Create new directories and files (my recommendation) ═══ To avoid mixing of distribution and generated files, you should put the new files into separate directories. Create two new directories named \LIBS and \OBJS under the existing IBMCPP\IOCDLL directory, p.e.. Copy the GETOBJS.CMD file into the new \OBJS. This is for backup and comfort. Note: You might need to change the old LIB command in the GETOBJS.CMD to ILIB according to the changes in VACPP. ═══ 1.3.3. Extract the object modules ═══ Extract the necessary object modules from the Open Class Library static library CPPOOC3.LIB using the GETOBJS.CMD. EXAMPLE: cd\ibmcpp\iocdll\objs GETOBJS ..\..\lib\CPPOOC3.LIB This will place the object modules into the new \objs\ directory. ═══ 1.3.4. Create the import library files ═══ Create the necessary import library files (CPPOOB3I.LIB, CPPOOU3I.LIB if you are going to relink the Multimedia and DDE- Dlls as well) with the existing definition files using the IMPLIB utility. EXAMPLE: cd.. IMPLIB .\libs\CPPOOB3I.LIB CPPOOB3.DEF IMPLIB .\libs\CPPOOU3I.LIB CPPOOU3.DEF This will create the needed import libraries. ═══ 1.3.5. Install the TrimDll Program ═══ Install the TrimDll program and its cross-reference files where ever you want. New DLLs, along with other created files, will be placed into that directory. Create an object for this if you like. You should now be ready to run the program following the instructions. There are two approaches to create a new response file:  Copy only the needed items from reference to the target box.  Copy all items from the reference to the target box and delete unneeded ones from the target. It's up to you which method you prefer, but you might leave more names in the target than needed if you choose the second method. See note in step 2.2.. ═══ 1.4. A Guided Introduction. ═══ Selectable Topics: Open a reference response file Select items to copy Copy items Delete items Create a new definition file Link the new DLL file Inspecting output Help for LNKXXXX Messages Restart after errors Saving your work Restart from a file Copy and Rename CPPOOx30.DLL Rename other DLLs Handle SYS2070 runtime errors ═══ 1.4.1. 1.0 Open a refence response file ═══ From the File Menu, OPEN a response file to work with. The .obj module names of that file will be displayed in the reference listbox. The target listbox will show the related indexes. This is to maintain the link order for best performance (recommended in the books). The appropriate definition file will be searched for. If not in the same directory as the .rsp file, processing is stopped here. Note: If you do not know which DLLs your appliction needs, run DLLRNAME from a command line and inspect the ouput. EXAMPLE: DLLRNAME myapp.exe The DLL names will be shown (among other referenced libraries). For example, if you find CPPOOB3.DLL in the list, you need CPPOOB3.RSP to open. ═══ 1.4.2. 2.0 Select items to copy ═══ To select items from the reference listbox:  Select a single item (click) or  Select a range of items (use the search dialog from the toolbar) or  Select a group of items by first checking the group option in the OPTIONS menu. Searches are done for prefix or full name only. A group is considered to be a modulename appended with a number, such as IRESLIB0.OBJ to IRESLIB4.OBJ, for example. Note: A successful search does not want selected items in the box, copy or deselect before the next search. HELPER: If you do not know which items to select, Doubleclick Right on an item. The classes supported by that object module will be displayed. However, this is only true if the selected name appears in the class-to-header reference of the 'Open Class Reference' book. Note: There are more .obj modules than .hpp files. ═══ 1.4.3. 2.1 Copy Items ═══ Click 'COPY' on the toolbar. A listbox within a dialog appears with all the candidates for copy. Note: In this box, you may find more module names than previously selected. The program follows the whole tree for the selected item and selects all referenced names. Uncheck 'SEARCH TREE' in the Options Menu to disable this feature. Although you can deselect items you do not want to be copied, this is not recommended for normal composition. All items are found to be referenced by a module within the tree and thus really needed. Click 'CANCEL' to end the operation or 'OK' to proceed. Selected items will be moved to the target, replacing the appropriate indices. ═══ 1.4.4. 2.2 Delete Items ═══ Use the select options described in step 2.0 to select items to delete from the target box. After clicking 'DELETE' on the toolbar, the dialog already described under 2.1 appears. Proceed as indicated there. Selected items will be deleted from the target and replaced by the appropriate indices. Do not delete DDE4UDLL, this is always required for the entrypoint. Note: For Delete, only directly referenced items are shown in the dialog box instead of the whole tree. You cannot delete items from the reference box. ═══ 1.4.5. 2.3 Proceed with copy/delete ═══ Proceed with steps 2.0 to 2.2 until you think you've all done. ═══ 1.4.6. 2.4 Create a new definition file ═══ Click on 'MAK DEF' on the toolbar. Enter the pathnames to the .OBJS and .LIBS files and the prefix of your target DLL name into the dialog. This prefix is used also for the new .RSP, .DEF, .MAP, .RST(restart), and .OUT(output) files. If the length of the name entered does not match the length of the original DLL name, a warning is given. You may reply with 'OK' for testing, but need to enter a name of equal lenght to later run DLLRNAME successfully. Note: DLLRNAME requires names of the same length. Check the 'MAP'-checkbox if you want a map. Click 'OK' to proceed. A single listbox with the new and completed response file will appear. This is only for reference and cannot be modified. The new definition file is created, but not shown. ═══ 1.4.7. 2.5 Link the new DLL file ═══ Click 'LINK DLL' on the toolbar. The ICC linker is called with the new response and definition file as input to link the new DLL. After termination, a message box is shown with the return code passed. Click 'OK' to continue. ═══ 1.4.8. 2.6 Inspecting Output ═══ If you want to see the output of the link step, click 'OUT' on the toolbar. You will see the output from the linker. Don't worry if you see plenty of errors, they may be based on missing only a few modules. Mainly, you will see LNK2022 (export undefined) and LNK2029 (unresolved external references) messages. ═══ 1.4.9. 2.7 Help for LNKXXXX Messages ═══ Getting this error messages indicates that one or more objects modules are missing. You may search for the module name associated with the function name in the message. Select a part or a whole phrase and doubleclick right. If found, the corresponding references to object modules will be displayed. LNK2022 - export undefined Up to the changes introduced by the CTx306 package, function names in this message were listed in mangled format. Try to select a meaningful part of the mangled names for the search. Note: The longer the selected phrase, the greater the chance to hit the right object module, the shorter the search time. LNK2029 - unresolved external reference Try to mark a complete class member function name, but avoid to hit the quotes. You may check first if the object module that causes the message is really required. Note: In this case, the search stops after the first match, which is usually the needed one. LNK4038 - program has no starting address If you get this message, you deleted DDE4UDLL.OBJ, the entrypoint module. This could also result in linker abending(?) with SYS3175 after LNK4001. ═══ 1.4.10. 2.8 Restart after Errors ═══ If you got errors and were notified of missing modules, select 'RESTART' from the toolbar. The target listbox will be restored and the appropriate response file will be loaded again. You may now proceed from step 2.0 to complete your response file. Use the search dialog to find the files. Repeat steps 2.0 to 2.5 until you got a zero return code in 2.5. Several passes may be necessary. ═══ 1.4.11. 2.9 Saving your work ═══ At any time after having modified the target you may 'SAVE' (from the file menu) the current status of the project. Doing just 'Save' will save the status under (dllname).RST if (dllname) is already known. Otherwise, the 'SAVEAS' dialog will be entered. 'SaveAs' will accept any name for the restart file. 'Save' is also called if you quit the program and the contents of the target box has changed. ═══ 1.4.12. 2.10 Restart from a file ═══ To restart from a file, select 'RESTART' from the file menu. The listboxes will be filled as after step 2.1, and you may proceed from there. The output button will be active in order to inspect the last result of the link step. ═══ 1.4.13. 2.11 Repeat for other DLLs ═══ Once you finished step 2.5 with RC0, you got a DLL (almost) ready to run. Repeat the sequence if you need to modify other DLLs. ═══ 1.4.14. 3.0 Rename DLL Names in your .exe and .dll modules ═══ You must tell your application files (.EXE and .DLL) about the new DLL names. ═══ 1.4.15. 3.1 Copy and Rename CPPOOS30/CPPOOM30.DLL ═══ First you need to copy and rename the standard libraries, CPPOOS30.DLL for single thread, or CPPOOM30.DLL for multithread apps. These are the C++ runtime DLLs and always needed. This has to be done from a command line. EXAMPLE: copy x:\ibmcpp\dll\CPPOM30.DLL y:\...(the current directory) DLLRNAME CPPOOM30.DLL CPPOM30=NEWOM30 rename the file DLLRNAME myapp.exe mydll.dll CPPOM30=NEWOM30 rename the name where myapp is your application name, mydll your application dll (if you made one using a class name function), and NEWOM30 the new name of the runtime DLL. ═══ 1.4.16. 3.2 Rename other DLLs ═══ Rename one ore more DLL names in your application EXAMPLE: DLLRNAME myapp.exe mydll.dll CPPOOB3=NEWB3DL CPPOOU3=NEWU3DL DLLRNAME myapp.exe mydll.dll CPPOOB3=NEWB3DL CPPOOU3=NEWU3DL where myapp is your application name, mydll your application dll (if you made one using a class name function), NEWB3DL and NEWU3DL your new runtime DLL names. ═══ 1.4.17. 4.0 Test your application. ═══ When running your application, you may happen to see SYS2070 errors with an error message like NEWU3DLL.NEWU3DLL->xxxx. This happens when a certain export is missing in your new dll. The xxxx is the ordinal number of this export within the referenced definition file. ═══ 1.4.18. 4.1 Handle SYS2070 Runtime Errors ═══ If you see SYS2070 errors when running your program, you need to search for the ordinals. Proceed as folllows:  Do a 'RESTART' from the toolbar or file menu and select the failing .RST file.  Select 'SEARCH ORDINAL' from the file menu.  Enter the number to search for and 'OK'. A messagebox with the search result will appear with the name of the missing object module. Take this name and restart as in step 2.8 or 2.10. Repeat step 4.0 and 4.1 until no more error messages. Skip step 3.0 if done once. Note: You should test all functions of your program, because the missing exports are not detected until the function executes. ═══ 1.5. Comments ═══ You may find all this still annoying, but if you have ever done all this before with an editor and in command mode, you will discover that using this program is much more comfortable, even if you decide to remove only the object module names recommended in the book.