如何使用inplace const char*作为std::string内容

4
我正在从事嵌入式软件项目。许多字符串存储在闪存中。我想使用这些字符串(通常是const char*const wchar*)作为std::string的数据。这意味着我想避免由于内存限制而创建原始数据的副本。
一个扩展用途可能是通过stringstream直接从闪存读取闪存数据。
以下是不幸无法就地工作的示例:
const char* flash_adr = 0x00300000;
size_t length = 3000;
std::string str(flash_adr, length);

非常感谢您的建议!


在某些平台上可能会出现这种情况。这有帮助吗? - Bernd L.
你可以通过链接脚本为它们提供符号,然后在固定的地址和保留的大小处进行对应。当然要坚持使用 const char* - πάντα ῥεῖ
13
请查看std::string_view - Captain Obvlious
1
@BerndL. 或许你可以提供一个基于 const char* 而非 std::stringstd::istream 实现。 - πάντα ῥεῖ
1
@Captain 你当然是指 std::experimental::string_view - Alan Stokes
显示剩余5条评论
2个回答

0

我现在已经使用了 CPP 核心准则中描述的 string_span(https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)。GSL 提供了完整的实现(GSL:Guidelines Support Library https://github.com/Microsoft/GSL)。

如果您知道字符串在闪存内的地址,您可以直接使用此构造函数来创建一个 string_span。

 constexpr basic_string_span(pointer ptr, size_type length) noexcept
    : span_(ptr, length)
{}

std::string_view可以像Captain Obvlious(https://stackoverflow.com/users/845568/captain-obvlious)所评论的那样完成相同的工作,这是我最喜欢的评论之一。

我对这个解决方案非常满意。从性能和可读性方面来看,它都表现得很好。


0

如果你愿意使用编译器和库特定的实现,这里有一个在MSVC 2013中可行的例子。

#include <iostream>
#include <string>

int main() {
    std::string str("A std::string with a larger length than yours");
    char *flash_adr = "Your source from the flash";
    char *reset_adr = str._Bx._Ptr; // Keep the old address around

    // Change the inner buffer
    (char*)str._Bx._Ptr = flash_adr;

    std::cout << str << std::endl;

    // Reset the pointer or the program will crash
    (char*)str._Bx._Ptr = reset_adr;

    return 0;
}

它将打印从闪存中获取的源代码

这个想法是保留一个能够容纳闪存中字符串的std::string,并不断更改其内部缓冲区指针。

您需要根据您的编译器进行自定义,而且一如既往地,您需要非常非常小心。


"C 让你容易地朝自己的脚开枪;C++ 让这个过程更难,但是如果你真的开了,整条腿都会被炸掉。" -- Bjarne Stroustrup - Charles
由于std::stringoperator<<()将范围为[str.begin(),str.end())的字符发送到流中,所以我认为你的结果纯属运气。 - Rumburak
这只是一个hack,由于平台依赖性和不安全性,我们永远不会使用这种解决方案。 - Bernd L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接