An NLM must have initialization code, a main body of code, and termination code. The following figure shows the structure of an NLM.
Figure 3-1 NLM Structure
The startup code is the entry point that allocates necessary resources and performs initialization so that an NLM can successfully run. For this code, you can use the LibC prelude file (libcpre), you can write your own customized startup function, or you can use the prelude startup code and add to it with your own customized code.
The prototype for the startup function is in the netware.h file. For more information, see _NonAppStart in Volume 2.
For shared libraries, you can use DllMain for the startup code. Its prototype is in windows.h. For more information, see DllMain in Volume 2.
The main body performs all the work of the NLM.
The check function is used to determine if an NLM can be safely unloaded. NLM applications that provide services for other NLM applications, such as a shared library, need a check function because a dependent module might still be using services. If an NLM does not provide services for other NLM applications, it does not need a check function.
The exit code needs to ensure that all resources are cleaned up and returned to the OS. Cleanup functions registered with the atexit function are called only when the NLM unloads normally. They are not called when the NLM is unloaded from the system console or when the NLM calls an abort routine. The cleanup functions registered with NXVmRegisterExitHandler are always called, regardless of how the NLM is unloaded.