dan*_*ang 2 c++ dll atl visual-studio-2015
我有一个要移植到 Win 10 的遗留项目。我们需要保持与 Windows XP 的兼容性,但我未能成功将转换后的项目甚至在 XP 下注册。为了了解什么是必要的(经过数周的 Stack Overflow 和 MSDN 搜索),我尝试使用 VS 2015 从头开始创建一个基于 ATL 的 Dll - 但它不起作用。在进一步讨论之前,让我先解决一些问题:
1) 是的,我已经安装了 VS 2015,并启用了对 XP 的 C++ 支持。2) 是的,我已经将平台工具集设置为 XP 3) 是的,我已经在 XP 目标上安装了 VS 2015 x86 可再发行组件包
如果我只是通过 ATL 项目向导并在添加任何 COM 接口之前停止,则 Dll 在 XP 上成功注册。如果我添加一个没有任何方法的接口,regsvr32 将失败并返回代码 0xc0000005。如果我向接口添加一个方法,并提供一个实现,它会继续以同样的方式失败。
如果您能提供丢失的部分,我将不胜感激。我生成最小 Dll 的过程大约需要 5 分钟的时间,以下是我的步骤(选择的设置最接近我想要移植的 Dll):
所需环境:
您将需要安装了 Visual Studio 2015 并启用 XP 支持的 Win 10 系统(如果在安装时未选中 XP C++ 支持选项,则会出现构建错误;它不是默认选项),并且
安装了 VS 2015 x86 可再发行组件的 Windows XP 系统(可在此处获得:https : //www.microsoft.com/en-us/download/details.aspx?id=48145)
打开VS 2015,选择文件/新建/新建项目...
• 从对话框左侧的已安装/模板/Visual C++/Windows 树中,选择“ATL”作为项目类型过滤器, • 从位于中心的模板列表中选择“ATL 项目”作为项目类型对话。• 从对话框顶部的下拉列表中选择“.NET Framework 3.5”作为.NET Framework • 将项目命名为“DllHoopty”, • 选择对话框右下方的“创建解决方案目录”选项。• 单击确定开始项目向导。
当项目向导出现时,当前项目设置应该是“Dynamic-Link Library”。
• 单击“下一步”,而不是“完成”
在“应用程序设置”页面上:
• 选择“允许合并代理/存根代码”, • 取消选择“安全开发生命周期 (SDL) 检查”。• 不选中“支持 MFC”和“支持 COM+ 1.0”。• 单击“完成”以创建项目和解决方案。
创建项目/解决方案后:
• 选择“Release”作为配置,选择“x86”作为平台。• 右键单击 DllHoopty 项目,然后选择“属性”。• 在属性对话框中,确保配置和平台分别为“Release”和“Win32” • 如果尚未选择,请转到“配置属性/常规”面板 • 将“平台工具集”更改为“ Visual Studio 2015 - Windows XP (v140_xp)” • 单击确定保存更改并关闭属性面板。
如果您停在这里并构建解决方案,则生成的 dll 将成功注册。
右键单击 DllHoopty 项目,然后从弹出菜单中选择“添加/类...”以打开“添加类”对话框 • 从树中选择“已安装/Visual C++/ATL”,从模板列表中选择“ATL 简单对象” • 单击“添加”开始 ATL 简单对象向导。
• 在“欢迎使用 ATL 简单对象向导”页面上,为对象指定 Hoopty 的“简称”。这将导致填写所有其他字段。 • 单击“下一步”。• 单击“文件类型处理程序选项”页面上的“下一步”
在“Options”页面上: • 选择“Single”作为线程模型, • 选择“No”作为“Aggregation”选项, • 选择“Custom”作为“Interface”选项。• 取消选中“自定义”下的“自动化兼容”框。• 应取消选中所有“支持”框。
• 单击“完成”
此时及以后,任何生成的 dll 都将无法注册并显示消息“DllHoopty.dll 中的 DllRegisterServer 失败。返回码为 0xc0000005”
打开文件“DllHoopty.idl”, • 添加“HRESULT Wub();” 到“接口 IHoopty”,例如将其更改为:
interface IHoopty : IUnknown{
HRESULT Wub();
};
Run Code Online (Sandbox Code Playgroud)
打开“Hoopty.h” • 添加:
STDMETHOD(Wub)();
Run Code Online (Sandbox Code Playgroud)
公开:CHOopty 类声明末尾的部分
打开“Hoopty.cpp” • 添加:
STDMETHODIMP CHoopty::Wub()
{
return S_OK;
}
Run Code Online (Sandbox Code Playgroud)
构建项目(确保 Release/x86 是选定的配置和平台)
• 将“DllHoopty.dll”移动到安装了 C++ 可再发行组件的 Win XP 机器上的本地硬盘驱动器(如果您像我一样使用带有 VirtualBox 的虚拟机,则不是共享文件夹)。
在 XP 计算机上: • 调出命令提示符, • 导航到 DllHoopty.dll 的位置, • 运行“regsvr32 DllHoopty.dll”。
如果我的猜测是正确的,您将收到一个错误对话框:
“DllHoopty.dll 中的 DllRegisterServer 失败。返回码为:0xc0000005”
我尝试了很多很多东西:为 WINVER 0x0501、_WIN32_WINNT 0x0501、_ATL_XP_TARGETING 以及其他许多我忘记的定义添加定义。没有什么能改变结果。
静态链接 CRT - 在配置属性/C/C++/代码生成/运行时库中选择非 DLL 多线程选项,例如/MT在发布版本中。
添加/Zc:threadSafeInit-(注意尾随-是开关的一部分)到配置属性/C/C++/命令行/附加选项下的编译器选项。
解决方法 #2 来自https://connect.microsoft.com/VisualStudio/feedback/details/1907257 上的公开案例。
Windows Server 2003 和 Windows XP 在动态加载使用线程本地存储的 DLL(通过 LoadLibrary)时存在问题,当静态本地已经初始化时,线程安全静态在内部使用它来提供高效执行。由于这些系统不受支持,因此极不可能为这些系统创建补丁来添加这种支持,因为 Vista 和较新的操作系统中存在这种支持,并且我们不愿意惩罚受支持的操作系统上的性能来提供这种支持旧的不支持的功能。
要解决此问题,您可以使用 /Zc:threadSafeInit- 禁用线程安全初始化代码,这将避免线程局部变量。当然,通过这样做,初始化代码会恢复到 VS2013 模式并且不是线程安全的,因此此选项仅在您不依赖本地静态的线程安全性时才可行。
| 归档时间: |
|
| 查看次数: |
2816 次 |
| 最近记录: |