【问题标题】:How can I expose a std::vector<std::string> via an extern "C" ABI?如何通过 extern "C" ABI 公开 std::vector<std::string> ?
【发布时间】:2020-08-31 05:16:17
【问题描述】:

我正在寻找通过 C ABI 访问字符串向量的正确方法。我的代码大致如下所示:

#include <iostream>
#include <vector>
#include <cstring>

// A C++ class containing information in a std::vector<std::string> that I want to expose in C (for eventually exporting to python via shared library)

class AVectorOfStrings{
private:
    std::vector<std::string> vec;
public:
    explicit AVectorOfStrings(std::vector<std::string> vec) : vec(std::move(vec)){}

    const vector<std::string> &getVec() const {
        return vec;
    }

    void setVec(const vector<std::string> &vec) {
        AVectorOfStrings::vec = vec;
    }
};

extern "C" {
    // function for accessing the strings
    char** getArrayOfCharStars(AVectorOfStrings* vec){
        std::vector<std::string> strings = vec->getVec();
        char **arr = (char **) malloc(strings.size() * sizeof(char *));

        for (int i = 0; i < strings.size(); i++) {
            arr[i] = (char *) malloc(sizeof(strings[i].c_str()));
            strcpy(arr[i], strings[i].c_str());
        }
        return arr;
    }

}
// usage
int main(){

    std::vector<std::string> input = {"1string", "2string", "3string"};
    AVectorOfStrings vec(input);

    char** arr = getArrayOfCharStars(&vec);

    // A bunch of attempts to access the three strings. 
    std::cout << *arr << std::endl;
    std::cout << *arr[1] << std::endl;
    std::cout << *(arr[1]) << std::endl;
    std::cout << **arr << std::endl;

    return 0;
};

此代码返回以下内容

1string
2
2
1

访问这些字符串的正确方法是什么?更一般地说,这是在 C++ 中处理字符串数组的正确方法吗?我的最终目标是以一种我可以使用ctypes 在 Python 中访问的方式存储字符串。

【问题讨论】:

  • 第二个sizeof应该是strlen(...) + 1。

标签: c++ char c-strings


【解决方案1】:

看来用pybind直接包装stlstd::vector&lt;std::string&gt;会简单很多。你有一个 here 的例子。

class AVectorOfStrings {
    std::vector<std::string> vec;
};

/* ... binding code ... */

py::class_<AVectorOfStrings>(m, "AVectorOfStrings")
    .def(py::init<>())
    .def_readwrite("contents", &AVectorOfStrings::contents);

【讨论】:

  • 非常有趣。我已经(并且必须)与ctypes 合作,但也许这两种沟通机制并不相互排斥。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2017-02-01
  • 1970-01-01
  • 2021-08-13
相关资源
最近更新 更多