短答案
因为我们测试过其他方案,只有这种方式是最好的。
长答案
在16位的Windows系统上,如果一个模块没有满足其所有的导入表,则它仍然可以被系统加载。只要你不调用一个丢失的导入项,则一切都还是正常的。如果你尝试调用一个丢失的导入项,程序将会立即崩溃并显示”不可恢复的错误”的对话框提示。
到了Win32时代,开发团队觉得这是一个很糟糕的设计,因为有时候人们会将一个为Windows 3.1开发的应用程序拷贝到Windows 3.0上并运行,一开始,这个应用程序运行的还不错,但是如果这个应用调用了一个只在Windows 3.1平台上可用的函数时(例如,GetSaveFileName这个函数),应用程序会立即崩溃。
因此Win32开发团队决定,如果有任何一个导入项没有被成功解析,则应用程序一开始加载的时候就会失败。如果上面例子中的应用程序开发商希望能将他们的应用运行在Windows 3.0上,则可以通过显式地使用GetProcAddress来表明这一点。因为如果必须显式调用GetProcAddress,则可能需要检查返回值。
当人们大声疾呼时,有时会出现此问题:”天哪,我应该有一种方法可以将导入项标记为’可选’-如果无法绑定,则加载应该不会失败。在调用绑定之前,应用程序有责任验证绑定是否成功。”,这些人可能是无意中在要求历史的重演,因为这又会回到我们一开始碰到问题的地方。
总结
如果对一个函数调用在当前平台上是否可用存在疑虑,可以尝试先用GetProcAddress来获取函数地址,如果函数不可用则进行相应的提示或者错误处理,尽量地让你的应用优雅的退出。