Visual Studio 2010 C++/CLI在静态库模式下:无法找到程序集'mscorlib.dll'。

17
我正在使用VS 2012在Dynamic Library (.dll)和x64模式下完成一个C++/CLI项目。
如果我将模式切换为Static Library,就会出现以下错误:
错误1 error C1107: could not find assembly 'mscorlib.dll': please specify the assembly search path using /AI or by setting the LIBPATH environment variable C:\Depot\Main\Current\Sln\ALibraryProject\Stdafx.cpp 1 1 ALibraryProject
我尝试删除对mscorlib.dll的引用,然后再从以下位置添加引用:
Project > Properties > General > Common Properties
但是这并没有起作用。由于我知道VS处理.NET组件的引用,因此我不想通过添加磁盘文件引用来解决这个问题,因为这似乎是不合逻辑的!有人面对过这个问题吗?
5个回答

44

当我将我的解决方案从VS2010编译器转换为VS2013编译器时,我遇到了同样的问题。

我通过更改项目设置(对于包含引发此错误的托管.cpp文件的项目)来解决它,如下所示:项目设置| C / C ++ |常规|其他#using目录中我添加了宏 $(FrameworkPathOverride)。 这将解析为您正在针对其的.NET版本的参考程序集目录,而在我的情况下为C:\Program Files(x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.1


1
当我从VS2010升级到VS2015时,我也遇到了相同的问题。我不确定为什么“Win32”配置已经有了“$(FrameworkPathOverride)”,但我必须将其添加到“x64”配置中。 - skst
我在VS2022中使用了宏 **$(MSBuildFrameworkToolsPath64)**,效果非常好! - Scott Madeux

5
如果我把模式切换为静态库
这不是您在启用/clr时尝试构建静态库时通常会遇到的错误。 我必须假设您已经调整了项目设置,以消除尝试执行此操作时出现的难以理解的链接器错误。
核心问题在于C++ / CLI构建系统不支持包含MSIL的静态库。 托管代码不使用链接器,在运行时进行绑定。 这使得静态库和DLL之间的本质区别消失。 因此,微软决定不支持它,因为实现它并没有太多意义。 不幸的是,当您尝试执行此操作时,他们没有大声喊叫,您收到的链接器错误没有足够明显的提示。 像与ILMerge合并之类的解决方法也无法解决问题,因为它无法处理混合模式程序集。 合并本机代码部分及其相关的关联表项非常复杂。
请记住,链接本机静态库是可以的。 典型的C ++ / CLI项目仅具有需要在启用/clr时构建的ref类包装器。 您可以将任意数量的来自库的本机代码粘合到最终程序集中。
我被迫推测实际的编译错误,因为太多程序员由于与构建静态库无关的“另一个”原因而遇到此错误,并且他们在评论中骚扰我。
请注意,针对与您计算机上安装的版本不同的.NET版本是非常危险的,特别是如果您想针对4.0并且已经安装了4.5.x。 您的.vcxproj文件中的关键元素是。 如果您开始针对旧的.NET版本启动项目,则将缺少此选项,您必须自行插入它。 IDE还不支持更改它(如果存在),再次手动编辑即可。
这足以促使MSBuild生成正确的编译命令。 您可以验证是否成功,查看您项目的Debug构建目录下的*.tlog子目录。 cl.command.1.tlog文件显示传递给编译器的选项。 它应该包含:
/AI“C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETFramework \ v4.0” /FU“C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETFramework \ v4.0 \ mscorlib.dll”
请注意子目录,非常重要,它必须与您打算的.NET目标匹配。 在本例中为v4.0。 而且非常非常重要的是,它不要指向c:\ windows \ microsoft.net,那是引用程序集的旧位置。

这与现实相去甚远。实际上,将程序集与本机代码合并非常容易(尽管不是真正推荐的做法)- 我已经做过几次了,事实上,我的工作之一就是在CLR程序集中包含本机代码 - 但是将它们合并后,我需要添加另一个构建步骤,而我想避免这样做...所以我选择了传统的方式,分别引用每个程序集。 - specializt
关于C++/CLI是一种“interop语言”的部分根本没有意义。我认为你需要对所选择的主题进行一些研究。Interop与语言本身无关,不能有任何“interop语言”- interop在某种程度上是语言之间的桥梁。请不要像硬性事实一样陈述你的假设和幻想。 - specializt
1
你在发牢骚。请发表一个回答。 - Hans Passant
4
被踩了,这并没有回答楼主的问题。解决方案请看@link1305的回答。 - tehlexx
非常晚才评论这个问题,但是我使用link1305在VS2012中的答案编译了一个托管C++静态库并与一个非托管可执行文件链接,没有任何问题。我遇到了与问题中完全相同的错误,但是托管C++不能用于静态库的答案似乎是错误的。我没有投反对票,因为它可能适用于过去的VC++版本。 - Jarra McIntyre
显示剩余2条评论

4
我有相同的问题。使用dll不起作用,因为我需要为.net对象提供本地C++包装器,以便它可以满足本地C++接口 - 我不能在dll接口中使用.net - 这会导致编译错误。
这在VS 2010(带有.net 4)中作为静态库运行良好。
我的一些可执行文件和dll也有一些代码/ clr。它们没有问题。我不尝试制作net库。

0

我通过移除旧的、未更新的混合库中的依赖来解决了这个问题,该库仅在“Debug”配置下进行了配置。结果,在我更改了一些代码后,它开始出现与你们相同的错误。

要找到这个问题并不简单,因为错误信息不够清晰,并且该依赖是通过项目设置中的“附加依赖项”进行设置的。


0
打开Visual Studio并卸载您的项目,然后进入项目文件夹并打开文件.vcxproj。搜索标签“targetFrameworkVersion”(如果不存在,则表示您的项目未使用.NET框架,因此无需更改)将其更改为所需版本,保存该文件。现在重新加载项目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接