为 Ruby FFI 接口(interface)从字符串转换为 const char* 时的 C++ 字符编码

标签 c++ ruby encoding ffi

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

必须将 std::stringint 错误代码传递给我的外部调用方。所以我在结构中返回这两个值:

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

不幸的是,我必须借助 std::c_str() 将 std::string 响应转换为 const char* C 风格的字符串表示形式 之前。原因:我的调用者是一个使用 Ruby FFI 与我的 C++ 库通信的 Ruby 脚本,这里的语言间类型转换是 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_encoding Ruby 端的字符串为ASCII-8BITISO-8859-15UTF- 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/

相关文章:

ruby - 如何在 Ruby 中创建段落?

javascript - nodejs pbkdf2sync 不是缓冲区错误

ios - Activesync:具有 MIME 类型的 Sendmail 命令

c# - response.write 编码错误

C++函数指针

c++ - Qt对象删除导致崩溃

c++ - 将 std::left 作为参数传递

c++ - 索引数组快速排序调试

ruby - 如何拆分数组?

ruby - 不确定的 IRB 完成行为?