我正在使用一个外部 C++ 库,它执行一些 HTTPS 通信并提供 XML 服务器响应。在服务器端,响应是通过 ISO-8859-15
编码的,我得到一个 std::string
表示来自 API 的响应。当我打印出来/将其写入文件时,它看起来是正确的。
必须将 std::string
和 int
错误代码传递给我的外部调用方。所以我在结构中返回这两个值:
extern "C" {
struct FoobarResponse {
const char* responseText;
int returnCode;
};
}
不幸的是,我必须借助 std::c_str() 将
之前。原因:我的调用者是一个使用 Ruby FFI 与我的 C++ 库通信的 Ruby 脚本,这里的语言间类型转换是 Ruby::string -> C::const char*。std::string
响应转换为 const char*
C 风格的字符串表示形式
这里很有趣:如果我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_encoding
Ruby 端的字符串为ASCII-8BIT
、ISO-8859-15
和UTF- 8
,没有变化。
在将字符串放入结构之前,我尝试在 C++ 端进行 base64 编码,并在 Ruby 端使用 this code 进行 base64 解码。 , 没有变化。
我也尝试过无数次使用 Iconv
转换字符串,但没有任何变化。
在将字符串放入结构之前,我还尝试从字符串中删除不可打印的字符,但我失败了。
我不知道这里发生了什么,而且选项用完了。 有人能指出我正确的方向吗?
问候 菲利克斯
最佳答案
一旦 std::string
超出范围,c_str()
返回的值就会被销毁。
如果您打算将此值传递给您的脚本,您应该分配内存并将字符串复制到新分配的空间中。请参阅此示例: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
关于为 Ruby FFI 接口(interface)从字符串转换为 const char* 时的 C++ 字符编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17942814/