PyBind11:绑定使用双指针的函数 [英] PyBind11: binding a function that uses double pointers

查看:783
本文介绍了PyBind11:绑定使用双指针的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将C ++函数与PyBind11绑定。问题在于此函数具有带双指针的参数,并且编译器引发错误

I would like to bind a C++-function with PyBind11. The problem is that this functions has an argument with a double pointer and the compiler raises an error

错误:无法初始化'char类型的参数右值类型为'typename make_caster< char **> ::: cast_op_type< typename std :: add_rvalue_reference< char **> :: type>'(又名'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对象转换为所需的逻辑

For non-simple argument types (e.g. like your char **) you'll have to wrap the function itself, where your wrapper provides the logic to go from a simpler type or a Python object to the desired type.

在这种情况下, char * 实际上是一种非常不安全的类型,因为它不会无法清除内存;为了使此功能更强大,您需要使用 std :: string s,然后可以从其中访问 char * 通过 c_str()方法。 (在pybind11中,即使您使用 char * 参数,这些实际上只是指向 std :: string 参数的指针: Python API故意让调用者访问Python字符串的内部存储。)

In this case, char * are actually a pretty unsafe type to work with, since it doesn't get memory cleanup; to make this work robustly you'll need to take std::strings, from which you can then access the char * via the c_str() method. (In pybind11, even when you take char * arguments, those are really just pointers into std::string arguments: the Python API deliberately doesn't let callers access the internal storage of Python strings).

因此,您只想将其与类型本身可以将整个内容公开为 char ** ,这几乎是 std :: vector 的含义设计要做。这是一个适合您示例代码的包装器:

So then you just want to combine it with a type that can itself expose the whole thing as a char **, which is pretty much what std::vector is designed to do. Here's a wrapper that would fit your example code:

#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 )。

(If your parse_args actually takes a const char ** you can drop the const_cast).

这篇关于PyBind11:绑定使用双指针的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆