【问题标题】:C++ STL and DLLsC++ STL 和 DLL
【发布时间】:2013-10-12 01:48:25
【问题描述】:

我知道这个问题已经多次以类似的方式被问过,但我并不肯定我已经完全掌握了这里涉及的概念。我目前正在做一些小的学习项目(因为我不久前停止使用 C++ 并想重新开始使用它),从我读到的内容来看,在 DLL 中使用 STL 时存在一些问题.

但是,根据我收集到的信息,有两种方法可以避免可能出现的问题。

方法一:DLL 的用户必须拥有相同的编译器和相同的 C 运行时库。

方法 2:隐藏所有 STL 类成员,无法直接访问。

但是,对于方法 2,我知道客户端无法直接访问 STL 类成员以使该方法起作用,但这是否意味着:

//Note all the code in this example was written directly in my web broswer with no checking. 

#ifdef SAMPLEDLL_EXPORTS
#define SAMPLE_API __declspec(dllexport) 
#else
#define SAMPLE_API __declspec(dllimport) 
#endif

class SAMPLE_API SampleClass
{
  std::map<int, std::string> myMap;

  public:
  SampleClass();
  ~SampleClass();

   void addSomething(int in_Key, char* in_Val)
   {
     std::string s(in_Val);
     myMap.insert( std::pair<int, std::string>(in_Key, s) );
   };

   bool getHasKey(int in_Key)
   {
      return myMap.find(in_Key) != myMap.end(); 
   };

};

行得通吗?

【问题讨论】:

  • 在这种特殊情况下,是的,因为所有代码都在标头中,DLL 中没有任何内容。可能不是你的意思。

标签: c++ dll stl


【解决方案1】:

正如 Hans Passant 在评论中指出的那样,您的示例有点可疑,因为您将所有方法定义都内联。但我们假设您将定义移动到单独的 .cpp 文件中,然后将其构建到 DLL 中。

这不安全。

从一开始,我们就有这个:

class SAMPLE_API SampleClass
{
  std::map<int, std::string> myMap;

我不需要再看下去了,因为我们可以立即看到 SampleClass 的大小取决于 std::map 的大小,而标准没有规定。因此,虽然您可以说 SampleClass 没有“公开”它的地图,但实际上它确实可以。您可以使用 Pimpl 技术来克服这个问题,并真正从您的班级的 ABI 中隐藏地图。

【讨论】:

  • 您介意解释一下 pimpl 是如何工作的吗?是因为地图只在 pimpl 起作用的实现中?
  • 这是因为映射的大小以及 impl 类的大小只需要在编译的 DLL 中知道,API 用户不需要知道。这是因为只有 DLL 会(取消)分配 impl 对象、使用它们等。Pimpl 只是更完全地隐藏了实现细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2014-02-03
相关资源
最近更新 更多