Escolar Documentos
Profissional Documentos
Cultura Documentos
1 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
2 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
3 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
4 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
5 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
6 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
7 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
8 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
9 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
10 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
goo
hooVar
kooVar
FOOGOO is the name or alias of the load module for the DLL. The prelinker puts out the DLL name in single quotation marks, and leaves enough extra blanks such that you can change FOOGOO to an 8-character name without moving the function or
variable name.
You can edit the definition side-deck to remove any functions or variables that you do not want to export. For instance, in the above example, if you do not want to expose goo(), remove the control statement IMPORT CODE 'FOOGOO' goo from the
definition side-deck.
Note: You should also provide a header file containing the prototypes for exported functions and extern variable declarations for exported variables. DLL application writers can then include this header file in their source files that reference functions or
variables in the DLL.
4. Build the DLL as you would any C application. For example, when using c89:
c89 -o foogoo ... foogoo.o ...
11/28/2014 7:06 AM
11 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
12 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
13 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
b. File 2:
extern void (*fp)(void);
void hello(void) {
printf("hello\n");
}
void goo(void) {
fp = hello;
}
If you do not use the DLL compiler option, fp would contain the address of hello. File 1 would expect fp to contain a function descriptor for fp, and the execution of fp would abend.
You must comply with all the rules described above when creating a complex DLL or DLL application. The prelinker flags violations of rule 2 as an error, but the compiler and prelinker do not indicate any other rule violations.
Note: A DLL or DLL application that does not comply with these rules may produce undefined run-time behavior. For a detailed explanation of incompatibilities between DLL and non-DLL code, see Compatibility Issues between DLL and Non-DLL Code.
To comply with the DLL rules, you should also be aware of the following:
1. A C source file will be compiled as DLL code if the DLL compiler option is on.
2. A C source file will be compiled as non-DLL code if the NODLL compiler option is on.
3. Other types of source files can be compiled only as non-DLL code.
11/28/2014 7:06 AM
14 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
15 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
16 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
17 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
18 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
19 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
20 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
5. DLL Restrictions
Consider the following restrictions when creating DLLs and DLL applications:
1. CEESTART must exist in the load module.
2. The AMODE of a DLL application must be the same as the AMODE of the DLL that it calls.
3. DLL facilities are not available under the SPC environment.
4. DLL facilities are not available to application programs with main() written in PL/I and that dynamically call C/C++ functions.
5. DLL facilities are not available to application programs written in COBOL and that dynamically call C/C++ functions.
6. You cannot implicitly load a DLL while running C++ static destructors.
7. You cannot use DLL static constructors to create new threads. This restriction is to prevent the creation of a DLL loop, where one DLL loads another, which then tries to load the first. In a single thread, if you try to create a DLL loop, you will get an error
message. However, Language Environment supports DLLs in a multithreaded environment. If a DLL static constructor could create threads, there might be a case where DLL A loaded DLL B, whose static constructor created a new thread that tried to load
DLL A before the static constructor for DLL B completed. The run-time library would not recognize this as a DLL loop. For this reason, DLL static constructors cannot create new threads.
8. You cannot use the functions set_new_handler() or set_unexpected() in a DLL if the DLL application is expected to invoke the new handler or unexpected function routines.
9. Be very careful when you use the explicit DLL functions in a multithreaded environment. Make sure you avoid any situation where one thread frees a DLL while another thread calls any of the DLL functions. Such a situation happens, for example, when a
main() function uses dllload() to load a DLL, then creates a thread that uses the ftw() function. The ftw() target function routine is in the DLL. If the main() function uses dllfree() to free the DLL, but the created thread uses ftw() at any point, you will get an
abend. There are many scenarios similar to this, all of which can be avoided if you do either of the following:
Do not free any DLLs by using dllfree(). (Language Environment will free them when the enclave is terminated.)
Have the main() function call dllfree() only after all threads have been terminated.
11/28/2014 7:06 AM
21 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
6. Performance Considerations
This section contains some hints on using DLLs efficiently.
Static Initialization in DLL code
Do not use the static initializations that require a DLL to be loaded if the code actually using the DLL may not be executed.
The static initialization of an external or static pointer variable to the address of an imported variable implies loading a DLL. Static initialization occurs when a DLL application begins executing, before C++ static constructors are run and before the execution
of the main function.
A DLL needed for the static initialization is always loaded at initialization time, even if the code using those pointers may not be executed later. To minimize unnecessary startup time, use a run-time initialization so that the DLL is loaded only if it is actually
used.
Group external variables
Group all external variables into one external structure.
POSIX Run-time Option and Loading DLLs
When POSIX(ON) is used, Language Environment always tries to load DLLs from the BFS first, then from the accessed CMS search order. If the DLLs actually reside on CMS minidisks or SFS directories, this results in unnecessary load attempts. If an
application must run with CMS DLLs, you can put two slashes (//) in front of the CMS DLL names before the application is prelinked, to make the DLL names in the side-decks unambiguous. If your application uses a DLL in the BFS, you can make the DLL
name unambigious by putting a period and a slash (./) in front of it before you prelink.
In C, do not compile with the DLL compiler option if the compilation unit does not use imported symbols.
11/28/2014 7:06 AM
22 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
23 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
Non-DLL
Imported Functions
A function descriptor is created by the prelinker. The descriptor is in the writable static Explicit reference is undefined 5
area (WSA) and contains the address of the function and the address of the writable
static area associated with that function. The function address is resolved when the
DLL is loaded. 1
Non-imported Functions
Also called by the function descriptor, but the function address is resolved at load
time. 3
Imported Variables
Undefined 6
A variable descriptor is created in the WSA by the prelinker. It contains addressing
information for accessing an imported variable. The address is resolved when the DLL
is loaded. 2
Non-imported Variables
Direct access 4
Direct access 8
11/28/2014 7:06 AM
24 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
25 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
26 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
In Figure 2, 1 causes a link error because the assignment to fp is undefined. 2 causes a prelink error because the assignment to xp is undefined. 3 assigns gp to the address of the non-imported function, g. 4 assigns the address of the non-imported variable y to
yp.
Figure 2. Pointer Assignment in Non-DLL Code
11/28/2014 7:06 AM
27 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
28 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
7.3.1. C Examples
Figure 1 shows an example of C non-DLL code in a DLL.
Figure 1. C Non-DLL Code in a DLL
int qqsort(int* z,int num,int (*comp)(int e1,int e2))
{
int i,j,temp,rc;
for(i=0;i<num-1;i++)
{
for(j=1;j<num-i;j++)
{
rc=(*comp)(z[j-1],z[j]);
if(rc>0)
{
temp=z j ;
z j =z j-1 ;
z j-1 =temp;
}
}
}
return(0);
}
int comp(int e1,int e2)
{
if(e1==e2){
return(0);
}
else if(e1<e2){
return(-1);
}
else{
return(1);
}
}
Figure 2 shows an example of C DLL code in a DLL application.
Figure 2. C DLL Code in a DLL Application
int (*comp)(int e1, int e2));
int comp(int e1, int e2)
{
if (e1 == e2)
return(0);
else (e1 < e2)
return(-1);
else
return(1);
}
int (*fp)(int e1, int e2);
main()
{
int a[2] = { 2, 1 };
fp = comp;
/* assign address of function descriptor */
qsort(a, 2, fp); /* call qsort */
}
Figure 3 shows an example of C non-DLL code in a non-DLL application.
Figure 3. C Non-DLL Code in a Non-DLL Application
int (*comp)(int e1, int e2));
int comp(int e1, int e2)
{
if (e1 == e2)
return(0);
else if (e1 < e2)
return(-1);
else
return(1);
}
int (*fp)(int e1, int e2);
main()
{
int a[2&] = { 2, 1 };
fp = comp;
/* assign function address */
qsort(a, 2, fp); /* call qsort */
}
Figure 4. DLL Function Pointer Call in Non-DLL Code
11/28/2014 7:06 AM
29 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
30 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
31 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
7.4.1. C Examples
C DLL code:
void (*fp)(void);
void main (void) {
goo();
(*fp)();
/* Expect a descriptor, but get a function address, */
/* so it de-references to an undefined address and */
/* call fails
*/
}
C Non-DLL code:
extern void (*fp)(void);
void hello(void) {
printf("hello\n");
}
void goo(void) {
fp = hello; /* assign address of hello, to fp
}
*/
11/28/2014 7:06 AM
32 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
*/
*/
C Non-DLL code:
{
int (*fp2)(const char *, ...);
fp2 = printf;
/* assign the address of printf.
*/
if (fp1 == fp2) /* comparing address of descriptor to
*/
/* address of printf results in unequal.*/
return(0);
else
return(1);
}
In the preceding example, DLL code and non-DLL code can reside either in the same load module or in different load modules.
Figure 1. Comparison of Function Pointers in Non-DLL Code
2. Comparing a DLL function pointer to another DLL function pointer. Here, you are comparing addresses of function descriptors. In the following examples, both DLL function pointers point to the same function, but they compare unequal (refer to Figure 2).
C DLL1 code:
extern int goo(int (*fp1)(const char *, ...));
main ()
{
int (*fp)(const char *, ...);
fp = printf; /* assign address of a descriptor that
/* points to printf.
if (goo(fp))
printf("Test result is undefined\n");
}
*/
*/
C DLL2 code:
extern int foo(int (*fp1)(const char *, ...),
int (*fp2)(const char *, ...));
int goo(int (*fp1)(const char *, ...))
{
int (*fp2)(const char *, ...);
fp2 = printf; /* assign address of a different
/* descriptor that points to printf.
return (foo(fp1, fp2));
}
*/
*/
C Non-DLL code:
int (*fp2)(const char *, ...))
{
if (fp1 == fp2) /* comparing the addresses of two
/* descriptors results in unequal.
return(0);
else
return(1);
*/
*/
}
Here, DLL1 code and DLL2 code reside in different load modules. The non-DLL code can reside in the same load module with DLL1 or DLL2 or in a different load module.
Figure 2. Comparison of Two DLL Function Pointers in Non-DLL Code
3. Comparing a DLL function pointer to a constant function address other than NULL. Here, you are comparing the constant function address to an address of a function descriptor.
Note: Comparing a DLL function pointer to NULL is well defined, because when a pointer variable is initialized to NULL in DLL code, it has a value zero.
11/28/2014 7:06 AM
33 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
11/28/2014 7:06 AM
34 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
*/
*/
11/28/2014 7:06 AM
35 of 35
http://pic.dhe.ibm.com/infocenter/zvm/v6r3/advanced/print.jsp?topic=/co...
"FUNCTION"
"VARIABLE"
11/28/2014 7:06 AM