如何在DLL边界上公开STL列表?

Ash*_*ain 8 c++ stl list abi pod

我有一个DLL,需要访问存储在主机应用程序中的STL容器中的数据.因为C++没有标准的ABI,并且我想支持不同的编译器,所以应用程序和DLL之间的接口基本上必须保持普通的旧数据.

对于向量,这是相对简单的.你可以简单地返回向量的内存块,因为它保证是有条件的:

// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
    if (!vec.empty())
        ptr = &(vec.front());

    count = vec.size();
}
Run Code Online (Sandbox Code Playgroud)

现在,DLL可以通过该接口对向量的数据进行安全的只读访问.DLL也可以包装它以将内容复制到自身的向量中.

那么STL列表(和deques)呢?是否有另一种直接允许通过DLL边界访问的方法?或者我是否必须使用某种GetFirst()/ GetNext()接口?我可能需要为很多列表执行此操作,因此有一个像vector一样简单的解决方案会很好.

mcd*_*ave 10

如果在实例化每个stl类型时要小心,可以在DLL之间传递stl对象并支持不同的编译器.您需要一些智能"DLLEXPORT"宏 - 我使用以下设置来成功支持VC和gcc.

#ifdef WIN32
#ifdef MYDLLLIB_EXPORTS      // DLL export macros
#define MYDLLLIB_API __declspec(dllexport)
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_API __declspec(dllimport)
#define MYDLLLIB_TEMPLATE extern
#endif
#else                       // Not windows --- probably *nix/bsd
#define MYDLLLIB_API
#ifdef MYDLLLIB_EXPORTS
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_TEMPLATE extern
#endif
#endif // WIN32
Run Code Online (Sandbox Code Playgroud)

编译DLL时,请定义MYDLLLIB_EXPORTS.然后,在DLL中,您可以实例化您希望使用的每个stl类型,例如,字符串的列表或向量

MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::vector<std::string>;
MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::list<std::string>;
Run Code Online (Sandbox Code Playgroud)

您的DLL的消费者(没有定义MYDLLLIB_EXPORTS)将会看到

extern template class __declspec(dllimport) std::vector<std::string>;
Run Code Online (Sandbox Code Playgroud)

并使用从DLL导出的二进制代码,而不是实例化自己的代码.

  • 它位于MSDN中:http://support.microsoft.com/default.aspx?scid = kb; EN-US; Q168958 (2认同)
  • MSDN文章(问题168958)不是说列表、地图和其他容器不能导出,只有向量可以吗? (2认同)

Nem*_*vic 7

也许你可以将像"handle"这样的东西传递给list/deque迭代器?这些句柄类型将是不透明的,并在您将发送给用户的头文件中声明.在内部,您需要将句柄值映射到list/deque迭代器.基本上,用户会编写如下代码:

ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();

while (lhi != lhe)
{
  int value = GetListItem(lhi);
  ...
  lhi = GetNextListItem(lhi);
}
Run Code Online (Sandbox Code Playgroud)