To create a complex DLL or DLL application, you must comply with the following rules that dictate how you compile source modules. The first decision you must make is how you should compile your code. You determine whether to compile with either the DLL or NODLL compiler option based on whether or not your code references any other DLLs. Even if your code is a DLL, it is safe to compile your code with the NODLL compiler option if your code does not reference other DLLs.
The second decision you must make is whether to compile with the default compiler suboption for DLL|NODLL, which is NOCBA, or use the alternative suboption CBA. This decision is based upon your knowledge of the code you reference. If you are sure that you do not reference any function calls through function pointers that point to a function entry rather than a function descriptor, use the NOCBA suboption. Otherwise, you should use the CBA suboption.
As of V2R4 of OS/390® C/C++, use the following options to ensure that you do not have undefined results as a result of the function pointer pointing to a function entry rather than a function descriptor:
Compile your C source modules as DLL when:
The comparisons shown in Function pointer comparison in non-DLL code are undefined. To obtain valid comparisons, compile the source modules as DLL code.
If the sort() routine in Figure 5 is compiled as DLL code instead of non-DLL code, non-DLL applications can no longer call it. To be able to call the DLL code version of sort(), the original non-DLL application must be recompiled as DLL code.
Consider the example programs shown in Table 1. You have the following two options when compiling them.
Source module 1 | Source module 2 |
---|---|
|
|
Table 2 summarizes some of the ways that you could compile the two source modules and list the results. Both modules are linked into a single executable.
How Modules Were Compiled | Result |
---|---|
|
fp contains a function descriptor. Execution of fp will succeed because it is valid to the address of a function descriptor. |
|
fp contains the address of hello. The execution of fp would abend because source module 1 expects fp to contain a function descriptor for hello. |
|
fp contains a function descriptor. The generated code will function correctly. It will run slower than if the source modules were compiled as DLL(NOCBA) because it will use Language Environment to make the function call. |
|
A call to Language Environment made by the function call through the function pointer prevents a problem that would have occurred had a direct function call been made. |
If you do not use the DLL compiler option, and your source module calls imported functions or imported variables by name, there will be unresolved references to these variables and functions at bind time. A DLL or DLL application that does not comply with these rules may produce undefined runtime behavior. For a detailed explanation of incompatibilities between DLL and non-DLL code, see Compatibility issues between DLL and non-DLL code.