在共享缓冲区内创建一个::std::string对象

3
我在一个内存有限的嵌入式应用程序中使用Google protobuf。我目前正在尝试使应用程序仅在必要时使用动态分配。为此,我有一些共享缓冲区,在其中创建所有proto消息或大部分消息。除了proto消息需要一个::std::string参数的情况外,一切似乎都很正常。
据我所知,::std::string构造函数的描述方式是它将创建我提供数据的副本。例如,这个构造函数:
s = new(sharedBufferAddress) ::std::string(mApn, mApnSize);

在哪里?
char                        mApn[APN_MAX_SIZE];
int8_t                      mApnSize;

将在共享缓冲区地址创建一个对象,但其中的数据将被复制到分配在堆上的缓冲区中。

问题是是否有一些方法可以将由c_str()函数返回的指针指向特定的地址。


相关链接:https://stackoverflow.com/questions/30057919/boost-unordered-map-in-shared-memory-using-stdstring-key 和 https://stackoverflow.com/questions/32581057/shared-memory-of-stdstring-give-segmentation-fault-linux - Galik
字符串将以自定义缓冲区分配器作为参数,因此这可能是您的前进方式。explicit basic_string( const Allocator& alloc ); - Gem Taylor
1
请原谅我对嵌入式系统的细节不太了解,但是难道不可能创建自己的分配器,以在任何地方(堆栈或堆)分配内存吗?如果我理解分配器的工作原理,您可以创建一个只能在堆栈上分配并在超出编译时允许的大小时抛出异常的分配器。该分配器应该是共享内存的管理器。 - The Quantum Physicist
std::stringstd::basic_string<char, std::char_traits<char>, std::allocator<char>> 的别名。编写自定义的 std::allocator<char>> 特化是未定义行为。因此,这里提到的方法似乎实际上并不合法。 - Öö Tiib
1
@ÖöTiib 到底是哪个变量未定义了?我无法理解你的意思,请重新表述或详细说明。 - The Quantum Physicist
显示剩余9条评论
1个回答

0

你不能对std::string的实现进行太多的黑客攻击。所有的尝试都会做一些非法的事情,并可能导致未定义的行为。

一个选择是演变出自定义的Protobuf实现或者对原始的Protobuf进行自定义修改。

另一个选择是使用现有的自定义实现。例如,芬兰程序员Petteri Aimonen已经在嵌入式开发中用C实现了Nanopb的Protobuf实现,并在zlib许可下发布。这可能比在嵌入式项目中使用自定义修改的原始Protobuf更有用,因为C和C++可以很好地协同工作。


谢谢您的回答,但更改协议消息过于复杂,因为还涉及其他公司。 - Moraru Gabriel
@MoraruGabriel 您没有描述需要在消息中使用什么类型和大小。 您可以使用其他类似的实现,这些实现支持更多类型/大小,例如https://github.com/protobuf-c/protobuf-c,或者您可以自己扩展它们。 如果您将所提议的更改作为拉取请求提供给它们,则很可能会免费对您的更改进行代码审查。 ;)如果涉及其他公司,则肯定要避免在其中黑客标准库或类,例如std :: string。 - Öö Tiib

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