SQL Server CE/Comapct uses Windows API LoadLibrary (PlatformBuilder or WinCE or Win32) to load the DLLs. When LoadLibrary fails to load any SQL CE dll, we throw the error “Can’t load sqlce dll”. Now, let’s discuss more on why LoadLibrary can fail.
1) Virtual Memory is too low to load the dll
2) Dependant DLLs are missing
3) Windows CE LoadLibrary has done something strange
Regarding point (2): Please run depends.exe on our DLLs and make sure your image has got all the required dependant DLLS. Note that, SQL Server CE stack depends on OLEAUTO.DLL, OLE.DLL. Some of the custom built images might not have selected Platform Builder catalog for COM Support and hence system fails to load the module.
Regarding point (1) and (3): Please read the KB Article 326163 completely as I am going to highlight few things from that article.
When a DLL is loaded in one process, Windows CE reserves that address space in every process address space. Multiple processes that use the same DLL share it at the same relative address in every process. If your application does not use the same DLL, it cannot use the memory that is reserved for that DLL. In other words, Windows CE does not map a RAM-based DLL at an address where another process maps another DLL. For example, if Process A loads DLL X at address 0x00970000, Windows CE does not map DLL Y in the Process B address space at 0x00970000. Instead, Windows CE seeks the next lower address that is available, depending on the size of DLL Y. So if DLL Y is in the size range of 128 KB, Windows CE selects 0x00950000 if that address is available for Process B. Because of the way that Windows CE allows processes to share a common DLL, Windows CE does not permit two different processes to load two different DLLs at the same relative address of each process.
Which means if there are many DLLs loaded by different processes; and your process is last to load your process LoadLibrary might fail as lot of address space is reserved.
The workarounds proposed from the article are:
If you determine that your application cannot load a DLL because of a lack of address space for the DLL, consider the following workarounds:
If your application is implemented in Microsoft C or Microsoft C ++, or if your eMbedded Visual Basic application uses custom DLLs, determine whether you use the VirtualAlloc function with the MEM_TOP_DOWN flag. When you use this flag, you allocate memory as high as possible, and you can cause DLLs to not load. VirtualAlloc must not use this flag.
If your application uses a lot of small custom DLLs, consolidate the code in one or two DLLs. The minimum address space that a DLL consumes is 64 KB. Therefore, for example, if you design your application so that thirty DLLs all fall between 8 and 10 KB, you waste 1,620 KB of address space.
Break the application down into more than one process. Use one process to load one set of DLLs and then use another to load a different set of DLLs. (Based on the application design, this may not be practical. If both processes must run simultaneously, then it does not help to use two separate processes.)
Load all your essential DLLs when you first load the application. If possible, keep the DLLs loaded. After you make this change in your application, watch to see if memory allocations or other processes do not work as a result. If they do, you must redesign your application to minimize DLL or memory.
Redesign the application to use less memory overall. Use only essential DLLs and then unload them if you do not require them. Minimize heap usage, as this impacts how many DLLs can load. Note that references to ActiveX objects do not unload when you set the object variable to Nothing.
The work around people could easily try out is (4) and it has worked for few of our customers. The other thing is to try unloading the unused modules using CoFreeUnusedLibraries (Win32 or WinCE) API if COM based applications have run.
Kruthagnyathalu / Dhanyavadamulu / Thanks,
Laxmi Narsimha Rao ORUGANTI