C++ 与Visual Studio C+合作+;清单文件
我已经编写了一些代码,利用开源库来完成一些繁重的工作。这项工作是在linux中完成的,通过单元测试和cmake帮助将其移植到windows。需要在两个平台上运行它 我喜欢Linux,我喜欢cmake,我喜欢能够自动生成visual Studio文件。现在,在windows上,一切都将编译,它将链接并生成测试可执行文件 然而,为了达到这一点,我不得不与windows进行几天的斗争,学习所有关于清单文件和可再发行软件包的知识 据我了解: 使用VS2005,Microsoft创建了并行DLL。其动机是,在此之前,多个应用程序将安装同一dll的不同版本,从而导致以前安装和工作的应用程序崩溃(即“dll地狱”)。并排dll解决了这个问题,因为现在每个可执行文件/dll都附加了一个“清单文件”,指定应该执行哪个版本 这一切都很好。应用程序不应该再神秘地崩溃。然而 微软似乎在每一次Visual Studio发布中都会发布一套新的系统DLL。另外,正如我前面提到的,我是一个试图链接到第三方库的开发人员。通常,这些东西以“预编译dll”的形式分发。现在,当使用一个版本的visual Studio编译的预编译dll链接到使用另一个版本的visual Studio的应用程序时,会发生什么情况 从我在互联网上看到的情况来看,坏事发生了。幸运的是,我从来没有走那么远——我在运行可执行文件时一直遇到“MSVCR80.dll not found”问题,因此开始了我对整个清单问题的探索 我最终得出结论,要让它正常工作(除了静态链接所有内容之外),唯一的方法是所有第三方库必须使用相同版本的Visual Studio进行编译-即不要使用预编译的dll-下载源代码,构建一个新的dll并使用它 这是真的吗?我错过什么了吗 此外,如果这似乎是事实,那么我不得不认为微软是出于邪恶的原因故意这么做的 它不仅破坏了所有预编译的二进制文件,使得使用预编译的二进制文件变得不必要的困难,如果您碰巧为使用第三方专有库的软件公司工作,然后,每当他们升级到最新版本的visual Studio时,您的公司现在必须执行相同的操作,否则代码将不再运行 另外,linux如何避免这种情况?虽然我说我更喜欢在它上面开发,并且我了解链接的机制,但我还没有维护任何应用程序足够长的时间来遇到这种低级共享库版本控制问题 最后,总结一下:这个新的清单方案是否可以使用预编译的二进制文件?如果是,我错在哪里?如果不是,微软真的认为这会使应用程序开发更容易吗 更新-一个更简洁的问题:Linux如何避免使用清单文件? 我最终得出结论,要让它正常工作(除了静态链接所有内容之外),唯一的方法是所有第三方库必须使用相同版本的Visual Studio进行编译-即不要使用预编译的dll-下载源代码,构建一个新的dll并使用它 或者(在我工作的地方我们必须使用的解决方案)是,如果您需要使用的第三方库都是使用相同的编译器版本构建的(或可用的编译版本),那么您可以“仅”使用该版本。例如,使用VC6可能是一种拖延,但如果你必须使用某个库,而它的源代码不可用,那么你的选择就非常有限 …据我所知。:)C++ 与Visual Studio C+合作+;清单文件,c++,visual-studio,dll,manifest,C++,Visual Studio,Dll,Manifest,我已经编写了一些代码,利用开源库来完成一些繁重的工作。这项工作是在linux中完成的,通过单元测试和cmake帮助将其移植到windows。需要在两个平台上运行它 我喜欢Linux,我喜欢cmake,我喜欢能够自动生成visual Studio文件。现在,在windows上,一切都将编译,它将链接并生成测试可执行文件 然而,为了达到这一点,我不得不与windows进行几天的斗争,学习所有关于清单文件和可再发行软件包的知识 据我了解: 使用VS2005,Microsoft创建了并行DLL。其动机是
(我的工作不在Windows中,尽管我们有时会从用户的角度与Windows上的DLL进行斗争,但是我们必须使用特定版本的编译器,并获得使用同一编译器构建的第三方软件版本。谢天谢地,所有供应商都倾向于保持相当的最新,因为他们一直在做这项工作应用程序中的所有组件都必须共享同一个运行时。如果不是这样,您会遇到奇怪的问题,例如断言delete语句 这在所有平台上都是一样的,不是微软发明的 您可以通过了解运行时在何处可能会起反作用来绕过“仅一个运行时”问题。 这主要是在一个模块中分配内存,然后在另一个模块中释放内存的情况下
a.dll
dllexport void* createBla() { return malloc( 100 ); }
b.dll
void consumeBla() { void* p = createBla(); free( p ); }
当a.dll和b.dll链接到不同的rumtime时,这会崩溃,因为运行时函数实现它们自己的堆
通过提供destroyBla函数,可以轻松避免此问题,必须调用该函数才能释放内存
您可能会在运行时遇到一些问题,但大多数问题可以通过包装这些结构来避免
供参考:
- 不要跨模块边界分配/释放内存/对象
- 不要在dll接口中使用复杂的对象。(例如std::string,…) <>不要在DLL边界上使用复杂的C++机制。(Type信息,C++异常,…)