Rules for Compiling DLL Code Versus Non-DLL Code
To create a complex DLL or DLL application, you must decide which source files should be compiled as DLL code and which should be compiled as non-DLL code. The following is a list of the rules for making that decision:
- A source file that contains a function call through a pointer that may point to either a function or function descriptor must be compiled as non-DLL code. For example, the qsort() routine in Figure 4 must be compiled as non-DLL code, because qsort() gets a pointer to a function to call. Because that pointer can be to a function compiled as either DLL code or non-DLL code, the qsort() routine emitted by the compiler cannot tell whether the routine to invoke is DLL or non-DLL code. This means that qsort() must be non-DLL. For additional information about function pointers, see Pointer Assignment.
- A source file that calls imported functions or imported variables by name must be compiled as DLL code.
- A source file that contains a comparison of function pointers
that may be DLL function pointers must be compiled as DLL code.
The comparisons shown in Function Pointer Comparison in Non-DLL Code are undefined. To obtain valid comparisons, you must compile the same source files as DLL code.
- A source file that may pass a function pointer to DLL code through
a parameter or a return value must be compiled as DLL code.
If the qsort() routine in Figure 4 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 qsort(), the original non-DLL application must be recompiled as DLL code.
- A source file that may pass a function pointer to DLL code by
linking the references to the definition of an external variable must
be compiled as DLL code.
In the following examples, if source file 1 has been compiled as DLL code, source file 2 must be compiled as DLL code as well.
- File 1:
void main(void) { goo(); /* initialize fp to be hello function */ fp(); /* call hello function */ } - 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.
- File 1:
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.
To comply with the DLL rules, you should also be aware of the following:
- A C source file will be compiled as DLL code if the DLL compiler option is on.
- A C source file will be compiled as non-DLL code if the NODLL compiler option is on.
- Other types of source files can be compiled only as non-DLL code.