[Edited with different findings – see bottom]
This one appears to be related to yet another compiler and/or Codegear / Borland IDE defect. Here is the story: For numerous months we have compiled our ActiveX OCX project and bundled it up in a CAB file with no problems. Recently however with the introduction of automating the build of this project in our build environment we started getting weird problems. I had already blogged about ‘weird enum values’ due to new defaults in project settings causing much grief, but this problem IU am discussing now definitely appears to be a “bug”.
When compiling from IDE in Release Mode, the resulting OCX file had exported 120 methods (using dependencywalker fromhere) while compiling the SAME cbproj from command line using msbuild exported only 115 methods! After checking Project settings I found that in Release Build Under C++ Compiler \ Debugging there is an option called ‘expand inline functions’. By default this is enabled in release mode. Unfortunately the IDE knows which methods NOT to expand (so that they can be exported so that the ActiveX control can load properly) while the command line MSBuild does NOT! Turning off this option and rebuilding from command line will once again restore the missing exported methods.
To confirm, copy the ocx to the %SYSTEMROOT%\Downloaded Program files\ folder and run:
if you get an error stating LoadLibrary(“yourctl.ocx”) failed – The specified procedure could not be found. Then you know you’re likely a victim of inline expansion on your ocx.
Why do I call it a bug? Because the IDE and command line builds should always product the exact same output when given the same project file and build settings.
Ok So it turns out the problem was not actually the compiler setting, but was the fact that a dependency in the ActiveX control was missing! We had added the Windows API call SetDllDirectory() and the side effect was that any system not running XP SP1 would crash with this error. This API was added as of XP SP1, for more details of requirements of the API look here. How did I find out? I tried to register the OCX control manually on the PC that was failing to install it, using regsvr32 yields the same error you see from the cdllogvw tool from Microsoft (which shows you ActiveX install log info). But using Codegear’s registration tool tregsvr.exe I actually got the REAL error, ‘could not find the procedure entry point for SetDLLDirectoryA in kernel32.dll’. To fix the issue don’t follow Microsofts recommendation in the MSDN documentation regarding LoadLibrary (which says to call SetDLLDirectory) rather call SetCurrentDirectory() before loading your DLL. Now you code runs on Windows 2000 and up!