c++ - PyBind11:绑定(bind)一个使用双指针的函数

标签 c++ c++11 pybind11

我想用 PyBind11 绑定(bind)一个 C++ 函数。问题是这个函数有一个带双指针的参数,编译器会报错

error: cannot initialize a parameter of type 'char **' with an rvalue of type 'typename make_caster<char **>::cast_op_type<typename std::add_rvalue_reference<char**>::type>' (aka 'char *') .

具体代码如下:

#include <pybind11/pybind11.h>

#include <iostream>

namespace py = pybind11;

void parse_args(int argn__, char** argv__)
{
  for(int i = 1; i < argn__; ++i)
    {
      std::cout<< argv__[i];
    }
}

PYBIND11_MODULE(argv_bind, m) {
   m.def("parse_args", &parse_args);     
}

最佳答案

对于非简单参数类型(例如 char ** ),您必须包装函数本身,您的包装器提供从更简单类型或 Python 对象到所需类型的逻辑。

在这种情况下,char *实际上是一种非常不安全的类型,因为它不会进行内存清理;为了使这项工作稳健地进行,您需要采取 std::string s,然后您可以从中访问 char *通过 c_str()方法。 (在 pybind11 中,即使您使用 char * 参数,它们实际上只是指向 std::string 参数的指针:Python API 故意让调用者访问 Python 字符串的内部存储)。

那么你只想将它与一个本身可以将整个事物公开为 char ** 的类型结合起来,这几乎就是std::vector被设计来做。这是适合您的示例代码的包装器:

#include <pybind11/stl.h>

m.def("parse_args", [](std::vector<std::string> args) {
    std::vector<char *> cstrs;
    cstrs.reserve(args.size());
    for (auto &s : args) cstrs.push_back(const_cast<char *>(s.c_str()));
    return parse_args(cstrs.size(), cstrs.data());
});

(如果您的 parse_args 实际上需要一个 const char **,您可以删除 const_cast)。

关于c++ - PyBind11:绑定(bind)一个使用双指针的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49195418/

相关文章:

c++ - 如何显示成对的模板化 vector ? [解决了]

C++ StackOverflowException 初始化超过 63992 的结构

c++ - OpenGL 顶点缓冲对象不起作用

c++ - 将 C++ 中的列表对象移动到另一个对象

pybind11 - 如何控制 std::function 的 pybind11 包装中的参数传递策略?

c++ - QTextBrowser 换行后的行间距

c++ - 通过使用范围解析避免多重继承引起的歧义

c++ - 难以理解 C++ 依赖类型,以及当前实例化的内容

python - 将嵌入式 python asyncio 集成到 boost::asio 事件循环中

python - pybind11 - ImportError : undefined symbol: _Py_ZeroStruct