安全的字符串复制超过DLL边界
Safe string copying over DLL boundaries
我试图使一个DLL暴露了一个特定的API,因此想实现一个安全的方式来复制字符串在DLL边界。DLL的实现非常直接——所有返回字符串值的函数都有两个参数——char*
和size_t&
。如果大小足够大I memcpy
从DLL内到给定指针的字符串的内容,设置大小为实际的大小,并返回一个成功的返回码。如果不是,我将大小设置为应有的大小并返回一个错误代码。DLL端非常简单。
现在更复杂的是-如何制作一个很好的模板函数,它给出了一个指向DLL中的一些函数的指针,将执行所有正确的操作来填充std::string
的实例。这是我得出的结论:
template<typename I>
CErrorCode GetStringValue(const I& Instance, CErrorCode(I::*pMethod)(char*, size_t&) const, std::string& sValue)
{
std::string sTemporaryValue;
size_t nValueLength = sTemporaryValue.capacity();
sTemporaryValue.resize(nValueLength);
do
{
auto eErrorCode = (Instance.*pMethod)(const_cast<char*>(sTemporaryValue.c_str()), nValueLength);
if (eErrorCode == CErrorCode::BufferTooSmall)
{
sTemporaryValue.resize(nValueLength);
}
else
{
if (eErrorCode == CErrorCode::NoError)
{
sTemporaryValue.resize(nValueLength);
sValue = std::move(sTemporaryValue);
}
return eErrorCode;
}
}
while (true);
}
所以我做了最初的resize
,因为我不能在第一次调用后这样做(因为它会擦除内容,因为字符串最初是空的)。但是resize
用零字符填充字符串,这让我有点不安(我的意思是我知道我要自己填充)。然后我需要resize
,即使在成功运行后,因为如果长度实际上更小,我需要调整大小。有什么建议,如果这可以做一个更好的方式?
既然你正在使用dll,我的理解是你是在Windows上,所以我将建议一个特定于Windows的解决方案。
在Windows上,COM内存分配器和BSTR
已经解决了安全传递字符串跨模块边界的问题。
所以,而不是传递一个字符串指针和一个大小指针,并检查调用者分配的缓冲区是否足够大,如果不返回所需的大小等,对我来说似乎更简单,只是从DLL返回 BSTR
s。
BSTR
使用COM分配器分配,因此您可以跨不同的模块边界分配和释放它们。
BSTR
周围也有很好的c++包装类,例如 _bstr_t
或ATL的 CComBSTR
。你可以在来电者的网站上使用。
一旦你有了一个BSTR
实例,可能在调用者的站点被一个方便的RAII包装器正确包装,你可以很容易地将它转换为std::wstring
。
或者,如果您想使用Unicode UTF-8编码和std::string
,您可以使用WideCharToMultiByte()
将BSTR
的本机UTF-16编码转换为UTF-8(这篇MSDN杂志文章可以派上用场)。
附加阅读:Eric 's Complete Guide To BSTR Semantics
注:
如果你不想使用BSTR
类型,你仍然可以使用COM提供的通用内存分配器:例如,你可以在DLL中使用 CoTaskMemAlloc()
分配(UTF-8)字符串内存,并在调用者的站点使用 CoTaskMemFree()
释放它。
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 是否可以跨 dll 边界返回常量引用/指向 std::vectors?
- 在 c++ 中的 dll 边界之间安全地传递数据
- 程序在Windows中的DLL边界上使用嵌入式Python/C 代码崩溃
- 使用抽象接口C++ dll 边界 -标头中的智能指针>?叫删除?
- 是否可以跨 DLL 边界传递 FILE 对象?
- 跨dll边界向构造函数抛出异常
- 使用跨DLL边界的单身人士
- 跨越dll边界的C++智能引用
- 在DLL边界上使用std::move是一种好的做法吗
- 通过dll边界的C字符串
- 跨DLL边界使用Direct2D
- 在 dll 边界上公开 std::vector语言 - 编译器独立性的最佳实践
- 通过dll边界传递对STL矢量的引用
- 我可以在DLL边界使用“enum class”作为函数的参数类型吗
- 如何在VC10中使用具有跨DLL边界的静态数据成员的模板类
- 在跨DLL边界使用的类中将字符串用作私有数据成员是否安全?
- 安全的字符串复制超过DLL边界
- 正确使用shared_ptr来消除跨DLL边界的释放
- 如何使用Boost.Log跨越DLL边界