5

我正在使用一个外部 C++ 库,它执行一些 HTTPS 通信并提供 XML 服务器响应。在服务器端,响应是通过编码ISO-8859-15的,我从 API 中得到一个std::string表示该响应的。当我将其打印出来/将其写入文件时,它看起来很合适。

std::string错误int代码必须传递给我的外部调用者。所以我在一个结构中返回两个值:

extern "C" {
  struct FoobarResponse {
    const char* responseText;
    int returnCode;
  };
}

不幸的是,我必须在之前的帮助下将std::string响应转换为const char*C 风格的字符串表示std::c_str()。原因:我的调用者是一个 Ruby 脚本,它使用 Ruby FFI 与我的 C++ lib 进行通信,这里的语言间类型转换是 Ruby::string -> C::const char*。

这里很有趣:如果我std::cout将转换后的字符串放入结构后,它仍然可以。

问题:在 Ruby 端处理服务器响应时,它被破坏了。而不是原来的答案,如:

<?xml version="1.0" encoding="ISO-8859-15"?>
<Foobar xmlns="http://www.foobar.com/2012/XMLSchema">
  ...
</Foobar>

我收到一个明显包含不可打印字符的字符串,该字符串在开头和结尾总是断开。

?O[
l version="1.0" encoding="ISO-8859-15"?>
<Foobar xmlns="http://www.foobar.com/2012/XMLSchema">
</Fo??

事实上,字符串至少包含换行符、回车符和制表符,也许更多。

我尝试将:force_encodingRuby 端的字符串设置为ASCII-8BIT,ISO-8859-15UTF-8, 没有变化。在将字符串放入结构之前,我尝试在 C++ 端进行 base64 编码,并在 Ruby 端使用此代码进行 base64 解码,没有变化。

我也有无数次尝试使用转换字符串Iconv,没有任何变化。

我还尝试在将字符串放入结构之前从字符串中删除不可打印的字符,但我失败了。

我不知道这里发生了什么并且没有选择。有人可以指出我正确的方向吗?

问候菲利克斯

4

1 回答 1

7

c_str()一旦std::string超出范围,返回的值就会被销毁。如果您打算将此值传递给脚本,则应分配内存并将字符串复制到新分配的空间中。请参阅此示例:http ://www.cplusplus.com/reference/string/string/c_str/

您还应该确保 ruby​​ 脚本将正确释放内存。

我认为这就是那里的解释:https ://github.com/ffi/ffi/wiki/Examples 。

从 C 传递给 Ruby 的结构示例: https ://github.com/ffi/ffi/wiki/Examples#-structs

于 2013-07-30T09:59:40.830 回答