C++ 如何导出模板化的C++;共享库中的类在Linux上工作?

C++ 如何导出模板化的C++;共享库中的类在Linux上工作?,c++,linux,boost,shared-libraries,C++,Linux,Boost,Shared Libraries,在Windows下,从DLL导出带有std::vector或boost::shared\u ptr字段的类几乎总是导致访问冲突。显然,Linux上不是这样,可以导入 class Test { public: boost::shared_ptr<SomeObscureClass> data; // ... } 类测试{ 公众: boost::共享的ptr数据; // ... } 从一个共享库到一个已经链接到Boost的程序,所有这些都可以工作。。。但是怎么做呢

在Windows下,从DLL导出带有
std::vector
boost::shared\u ptr
字段的类几乎总是导致访问冲突。显然,Linux上不是这样,可以导入

class Test {
public:
     boost::shared_ptr<SomeObscureClass> data;

     // ...
}
类测试{
公众:
boost::共享的ptr数据;
// ...
}
从一个共享库到一个已经链接到Boost的程序,所有这些都可以工作。。。但是怎么做呢

据我所知,Windows案例中崩溃的主要原因是主程序和共享库都有
boost::shared_ptr
方法的模板实例,因此,例如,
delete
和静态字段混淆,这导致了不好的结果


但在Linux上,它显然工作得很好!我已经看到了至少五种不同的C++库,它们是在Linux上开发的,它们被内置到共享库中,并且有<代码> STD::/COD>字段,并且显然不会遇到任何问题。这是如何工作的?

与模板实例化相关的符号与其他符号没有任何区别

在Linux上,共享库会导出所有未显式设置为私有的符号,因此进程将只使用“第一个”库提供的符号(如果希望共享库使用主可执行文件提供的符号,您可能需要更加注意您的选项,但也可以这样做)。您可以将符号显式地私有化,并在需要时使用它提供的共享库;在过去,您必须使用链接器脚本,现在,gcc提供选项和属性来帮助细粒度控制


我的理解是(但我不是Windows方面的专家,这正是我在类似这样的论坛上读到的),在Windows上,默认设置是反向的,所有未明确公开的符号都是私有的,但你可以通过更改符号的属性来解决问题(我不知道这有多容易或难).

您提到的windows行为并不完全正确。只要使用/MD(d)选项,就可以导出包含std组件的类。这会动态链接C++运行时,而不是将其编译成代码。Linux的行为类似,您需要链接到.so runtime
boost::which
不在VS runtime中,这会导致问题。无论如何,运行时就是不能在其中实现,比如说,
boost::shared_ptr::operator*
,因为它不知道
someobscreclass
。您可以使用编译boost库来控制导出的接口。问题在于符号可见性&而不是操作系统的某些限制。经验法则是,如果导出资源获取函数,则还必须导出相应的清理函数。Hmmm。我对它的理解是否正确:比如说,如果一个内部使用boost::shared_ptr的共享库在一个根本不使用boost的程序中使用,它仍然可以工作,因为它有所有需要的模板实例。但是,如果程序确实使用了Boost,那么该库将不会使用它自己的Boost函数,而是使用主程序中的函数?很可能您将使用共享Boost库,而不是在共享库中包含和导出它们。因此,在这两种情况下,boost中的符号都来自boost库。可以多次出现的(整个程序使用一致的)是生成的模板或内联函数。(是的,整个程序将必须使用一致的boost库进行编译,这就是为什么您可能希望将一些符号设置为私有的,而不是为接口相关的东西提供内联函数)。共享库不是很难实现,但无论您使用什么系统,如果您希望库真正可用,那么库必须设计为共享的。遗憾的是,我不知道有什么好的介绍这个主题的。