题
我有需要访问存储在STL容器在主机应用程序的数据的DLL。因为C ++没有标准ABI,我要支持不同的编译器,应用程序和DLL之间的界面基本上具有保持普通老式的数据。
有关载体中,这种相对简单。可以简单地返回向量的存储块,因为它被保证是contigious:
// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
if (!vec.empty())
ptr = &(vec.front());
count = vec.size();
}
现在该DLL可以具有经由接口向矢量的数据安全只读访问。所述DLL也可以包裹这对中的内容复制到一个向量本身以及
有关STL列表(和双端),虽然是什么?是否有另一种简单的方法,使通过DLL边界的访问?或将我不得不求助于某种GetFirst()/的GetNext()接口的?我可能需要为大量的名单做到这一点,所以它会是不错的解决方案那么简单,矢量的。
解决方案
也许你可以通过类似“手柄”列出/ deque的迭代器?这些句柄类型是不透明的,并宣布在头文件,你会运送到用户。在内部,你会需要映射的句柄值列出/ deque的迭代器。基本上,用户将写像代码:
ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();
while (lhi != lhe)
{
int value = GetListItem(lhi);
...
lhi = GetNextListItem(lhi);
}
其他提示
您可以通过DLL文件之间的STL对象,并支持不同的编译器,如果你你实例每个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
当编译您的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>;
然后您DLL的消费者(谁没有定义MYDLLLIB_EXPORTS)会看到
extern template class __declspec(dllimport) std::vector<std::string>;
和使用的实例,而不是自己从DLL导出的二进制代码。
应用程序之间的接口 和DLL主要有留 普通老式的数据。
不一定。你必须确保在相同的编译器版本使用。此外,建立设置,影响STL对象的布局是DLL和应用程序之间的完全一样。
如果你要释放出来的DLL到野外,你是正确的跨越DLL边界暴露STL有关。但是,如果一切都在你的控制之下,纯属内部(或者,如果你能严格执行第三方构建设置/编译)你应该罚款。