在不同CRT的库之间使用shared_ptr<T>

3

我正在编写一个库,其中包括一个接口以返回/接收 shared_ptr 对象。

一切都很顺利,直到我想起使用我的库的应用程序可能具有不同的 CRT 版本和 STL 版本。

这引出了两个问题:

  1. 如果我的 .lib 文件和使用它的应用程序之间的 STL 版本不同,如何确保在我的库和应用程序中使用相同版本的 shared_ptr?(STL 不提供二进制兼容性)

  2. 假设我通过复制 STL 定义 shared_ptr 的头文件并将其重命名为 my_shared_ptr 或以任何方式解决了问题 1,现在我可以在我的库和应用程序中使用相同的 shared_ptr 实现。但是,由于这是一个模板类,并且 CRT 版本不同,我该如何确保 new 拥有匹配的 delete?如果我的库编译 my_shared_ptr<SomeClass>,而应用程序编译 my_shared_ptr<SomeClass>,则每次编译都会根据 CRT 版本插入自己的 newdelete。现在,当我从应用程序创建并传递一个 shared_ptr 给我的库,以便在使用完毕后销毁它时,可能会调用不匹配的 newdelete

我应该假设需要编译两个 my_shared_ptr<SomeClass> 的实例,一个由 .lib 文件编译,另一个由应用程序编译吗?

感谢任何帮助, Leo


shared_ptr与STL没有任何关系。 - curiousguy
1个回答

1
据我所知,你不能轻易地做到这一点,尽管你可以想象创建一个二进制兼容的共享智能指针类,例如,在Microsoft平台上使用COM对象。你仍然必须确保分配和解分配都发生在同一个DLL中。这意味着替换你的智能指针类的“new”和“delete”,将调用从你的DLL导出的函数,这些函数保证调用正确的新的和删除的实现。

你知道如果库和应用程序都使用my_shared_ptr<SomeClass>会发生什么吗?这个类会被实例化两次吗?如果是的话,分别在哪里实例化,是在库还是应用程序中? - Leo
@Leo。该类被实例化两次。如果在这样的类中有静态成员,这可能会让你感到惊讶:你将拥有静态成员的两个实例,一个在应用程序中,另一个在DLL中(如果应用程序和DLL都链接到相同的静态库,则也可能发生这种情况)。 - Joris Timmermans
谢谢,这是由C++标准规定的吗?你能给我提供任何相关标准的参考吗? - Leo
此外,如果是这种情况,我可以解决匹配 new 和 delete 的问题。shared_ptr 指向一个带有虚拟成员 delete() 的引用计数块。该块将从应用程序传递到库,并最终调用包含匹配的 delete 的适当虚拟方法,不是吗? - Leo
@Leo - 如果虚方法的实现是从应用程序内部编译的,那么你仍然会遇到麻烦。智能指针必须调用从 DLL 中导出的非模板类。这个类可以是你自己的自定义智能指针类。 - Joris Timmermans
显示剩余2条评论

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