【问题标题】:Problems creating a char array from a QMap of QString从 QString 的 QMap 创建 char 数组时出现问题
【发布时间】:2018-10-23 15:14:03
【问题描述】:

我正在使用 libxslt C 库,并且需要将参数作为const char * 传递。我将库包装在 Qt C++ 类中,因此存储在 C++ 类中的参数存储为QMap<QString, QString>

我的第一次尝试很简单:

const char *params[32];
int index = 0;
if (m_params.size() > 0) {
    QMapIterator<QString, QString> it(m_params);
    while (it.hasNext()) {
        it.next();

        params[index++] = it.key().toLocal8Bit().data();

        params[index++] = it.value().toLocal8Bit().data();
    }
}

params[index++] = nullptr;

qDebug() << params[0] << params[1]; // 0 0

但我意识到这不起作用,因为来自toLocal8bitQByteArray 几乎在我使用它时就超出了范围。

我尝试过使用 strcpy - 但有相同的范围问题:

m_params.insert("some-key", "some-value", "another-key", "another-value");

if (m_params.size() > 0) {
    QMapIterator<QString, QString> it(m_params);
    while (it.hasNext()) {
        it.next();

        char buffer[32];

        strcpy(buffer, it.key().toLocal8Bit().data());
        params[index++] = buffer;

        strcpy(buffer, it.value().toLocal8Bit().data());
        params[index++] = buffer;
    }
}

params[index++] = nullptr;

qDebug() << params[0] << params[1]; // another-value another-value

所以现在我有一个具有相同值的参数列表。

当我手动设置所有值时,我得到了预期的结果:

const char *params[32];
int index = 0;

params[index++] = "something";
params[index++] = "something-else";

params[index++] = nullptr;

qDebug() << params[0] << params[1]; // something something-else

【问题讨论】:

  • const char *params[(m_params.size() * 2) + 1]; -- 除非m_params.size() 是编译时常量,否则这不是有效的 C++ 代码。
  • @PaulMcKenzie 谢谢 - 有没有办法克服这个问题 - 否则我要么过度分配要么限制我可以设置的参数数量。
  • @codekaizer - 不确定你的副本如何帮助解决这个问题
  • @HorusKol -- std::vector&lt;char *&gt;(m_params.size() * 2 + 1) params;

标签: c++ arrays qt char


【解决方案1】:

这很容易 - 您需要确保参数的缓冲区持续足够长的时间。不要使用固定大小的数组 - 你正在为缓冲区溢出做准备。

class Params {
  QByteArray buf;
  QVector<const char *> params;
public:
  Params() = default;
  template <class T> explicit Params(const T& map) {
    QVector<int> indices;
    indices.reserve(map.size());
    params.reserve(map.size()+1);
    for (auto it = map.begin(); it != map.end(); ++it) {
      indices.push_back(buf.size());
      buf.append(it.key().toLocal8Bit());
      buf.append('\0');
      indices.push_back(buf.size());
      buf.append(it.value().toLocal8Bit());
      buf.append('\0');
    }
    for (int index : qAsConst(indices))
      params.push_back(buf.constData() + index);
    params.push_back(nullptr);
  }
  operator const char **() const { return const_cast<const char**>(params.data()); }
  operator const char *const*() const { return params.data(); }
  operator QVector<const char*>() const { return params; }
};

void MyClass::method() const {
  Params params{m_params};
  ...
  res = xsltApplyStylesheet(cur, doc, params);
  ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多