我有一个要移植到Win 10的旧项目。我们需要保持与Windows XP的兼容性,但我无法使转换后的项目甚至在XP下注册也没有成功。为了了解什么是必要的(在搜索了Stack Overflow和MSDN几周之后),我尝试使用VS 2015从头开始创建基于ATL的Dll,但它不起作用。在继续之前,让我先解决一些问题:
1)是的,我已经安装了启用了XP的C++支持的VS 2015。
2)是,我已将平台工具集设置为XP
3)是的,我已经在XP目标上安装了VS 2015 x86可再发行组件包
如果我只是通过ATL项目向导并在添加任何COM接口(interface)之前停止,那么Dll将在XP上成功注册。如果添加没有任何方法的接口(interface),则regsvr32失败,返回码为0xc0000005。如果我向接口(interface)添加方法并提供实现,则该方法将继续以相同的方式失败。
如果您能提供缺少的那一部分,我将不胜感激。我生成最小Dll的过程大约需要5分钟的时间,这是我的步骤(选择设置以最接近我要移植的Dll):
所需环境:
您将需要一个Win 10系统,其中安装了启用了XP支持的Visual Studio 2015(如果在安装时未选中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”,
•选择对话框右下方的“创建解决方案目录”选项。
•单击确定以启动项目向导。
当出现项目向导时,当前项目设置应为“动态链接库”。
•单击“下一步”,而不是“完成”
在“应用程序设置”页面上:
•选择“允许合并代理/存根代码”,
•取消选择“安全开发生命周期(SDL)检查”。
•取消选中“支持MFC”和“支持COM + 1.0”。
•单击“完成”以创建项目和解决方案。
创建项目/解决方案后:
•选择“发布”作为配置,选择“x86”作为平台。
•右键单击DllHoopty项目,然后选择“属性”。
•在属性对话框中,确保配置和平台分别为“Release”和“Win32”
•如果尚未选择,请转到“配置属性/常规”面板
•将“平台工具集”更改为“Visual Studio 2015-Windows XP(v140_xp)”
•单击确定保存更改并关闭属性面板。
如果您在此处停止并构建解决方案,则生成的dll将成功注册。
右键单击DllHoopty项目,然后从弹出菜单中选择“添加/类...”以弹出“添加类”对话框。
•从树中选择“已安装/ Visual C++ / ATL”,然后从模板列表中选择“ATL简单对象”
•单击“添加”以启动ATL简单对象向导。
•在“欢迎使用ATL简单对象向导”页面上,为对象指定Hoopty的“短名称”。这将导致其他所有字段都被填写。
• 点击下一步”。
•单击“文件类型处理程序选项”页面上的“下一步”
在“选项”页面上:
•选择“单一”作为线程模型,
•选择“否”作为“汇总”选项,
•选择“自定义”作为“接口(interface)”选项。
•取消选中“自定义”下的“自动化兼容”框。
•应取消选中所有“支持”框。
•单击“完成”
在这一点及以后,生成的任何dll都将无法向消息“DllHoopty.dll中的DllRegisterServer失败”进行注册。返回码为0xc0000005”
打开文件“DllHoopty.idl”,
•添加“HRESULT Wub();”到“接口(interface)IHoopty”,例如更改为:
interface IHoopty : IUnknown{
HRESULT Wub();
};
打开“Hoopty.h”
•添加:
STDMETHOD(Wub)();
对公众:CHoopty类声明末尾的部分
打开“Hoopty.cpp”
•添加:
STDMETHODIMP CHoopty::Wub()
{
return S_OK;
}
生成项目(确保Release / x86是所选的配置和平台)
•在安装了C++可再发行组件的Win XP计算机上,将“DllHoopty.dll”移动到本地硬盘驱动器(如果像我一样,将虚拟机与VirtualBox一起使用,则不要共享文件夹)。
在XP机器上:
•弹出命令提示符,
•导航到DllHoopty.dll的位置,
•运行“regsvr32 DllHoopty.dll”。
如果我的猜测是正确的,您将看到一个错误对话框:
“DllHoopty.dll中的DllRegisterServer失败。返回码为:0xc0000005”
我尝试了很多事情:为WINVER 0x0501,_WIN32_WINNT 0x0501,_ATL_XP_TARGETING添加定义,以及其他很多我忘记的定义。什么都不会改变结果。
最佳答案
/MT
。 /Zc:threadSafeInit-
(n.b。尾随的-
是开关的一部分)。 解决方法#2来自https://connect.microsoft.com/VisualStudio/feedback/details/1907257处的打开案例。
Windows Server 2003 and Windows XP have problems with dynamically loading a DLL (via LoadLibrary) that uses thread-local storage, which is what thread-safe statics use internally to provide efficient execution when the static local has already been initialized. As these systems are out of support, it is extremely unlikely for a patch to be created for those systems to add this support as is present in Vista and newer OSes, and we are reluctant to penalize the performance on in-support OSes to provide this functionality to the old out-of-support ones.
To work around the issue you can use /Zc:threadSafeInit- to disable the thread-safe initialization code and this will avoid the thread-local variable. Of course by doing so the initialization code reverts back to the VS2013 mode and is not thread-safe, so this option is only viable if you don't rely on the thread-safety of local statics.
关于c++ - Visual Studio 2015无法产生在Windows XP上成功注册的ATL Dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34074204/