我正在寻找一种方法将一些数据填充到DLL边界的字符串中.因为我们使用不同的编译器,所有的dll接口都是简单的char*.
是否有正确的方法将指针传递给dll函数,以便它能够直接填充字符串缓冲区?
string stringToFillIn(100, '\0');
FunctionInDLL( stringToFillIn.c_str(), stringToFillIn.size() ); // definitely WRONG!
FunctionInDLL( const_cast<char*>(stringToFillIn.data()), stringToFillIn.size() ); // WRONG?
FunctionInDLL( &stringToFillIn[0], stringToFillIn.size() ); // WRONG?
stringToFillIn.resize( strlen( stringToFillIn.c_str() ) );
Run Code Online (Sandbox Code Playgroud)
看起来最有希望的是&stringToFillIn [0]但是这是一个正确的方法,假设你认为string :: data()==&string [0]?这似乎不一致.
或者最好是吞下额外的分配并避免问题:
vector<char> vectorToFillIn(100);
FunctionInDLL( &vectorToFillIn[0], vectorToFillIn.size() );
string dllGaveUs( &vectorToFillIn[0] );
Run Code Online (Sandbox Code Playgroud)
CAd*_*ker 24
我不确定标准是否保证a中的数据std::string存储为char*.我能想到的最便携的方法是使用a std::vector,保证将其数据存储在连续的内存块中:
std::vector<char> buffer(100);
FunctionInDLL(&buffer[0], buffer.size());
std::string stringToFillIn(&buffer[0]);
Run Code Online (Sandbox Code Playgroud)
这当然需要将数据复制两次,这有点效率低下.
mar*_*h44 18
经过更多阅读和挖掘之后,我发现string :: c_str和string :: data可以合法地返回一个指向缓冲区的指针,该缓冲区与字符串本身的存储方式无关.例如,字符串可能存储在段中.写入这些缓冲区对字符串的内容有不确定的影响.
另外,string :: operator []不应该用于获取指向字符序列的指针 - 它应该只用于单个字符.这是因为指针/数组的等价不适用于字符串.
对此非常危险的是,它可以在某些实现上工作,但在未来的某个日期突然中断,没有明显的原因.
因此,正如其他人所说的那样,唯一安全的方法是避免任何尝试直接写入字符串缓冲区并使用向量,将指针传递给第一个元素,然后从向量返回的向量中分配字符串. DLL功能.
在C++ 98你不应该改变由返回的缓冲区string::c_str()和string::data().另外,正如其他答案中所解释的那样,你不应该使用它string::operator[]来获取指向一系列字符的指针 - 它应该只用于单个字符.
从C++ 11开始,字符串使用连续的内存,因此您可以使用&string[0]访问内部缓冲区.
只要C ++ 11提供连续的内存保证,在生产实践中,这种“ hacky”方法就很受欢迎:
std::string stringToFillIn(100, 0);
FunctionInDLL(stringToFillIn.data(), stringToFillIn.size());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31054 次 |
| 最近记录: |