- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关注 this post ,我想知道如何通过 Pybind11 将字符串列表从 Python 传递到 C(即,使用 C header 和语法,而不是 C++)。我完全知道 Pybind11 是一个 C++ 库,并且代码无论如何都必须由 C++ 编译器编译。但是,我很难理解 C++ 的实现,例如 here和 here .
Here我试图通过指针传递一个 python 字符串列表,表示为整数,然后通过 long*
接收它们。在 C 中,但它没有用。
C/C++ 代码应该类似于:
// example.cpp
#include <stdio.h>
#include <stdlib.h>
#include <pybind11/pybind11.h>
int run(/*<pure C or pybind11 datatypes> args*/){
// if pybind11 data types are used convert them to pure C :
// int argc = length of args
// char* argv[] = array of pointers to the strings in args, possible malloc
for (int i = 0; i < argc; ++i) {
printf("%s\n", argv[i]);
}
// possible free
return 0;
}
PYBIND11_MODULE(example, m) {
m.def("run", &run, "runs the example");
}
CMakeLists.txt
还提供了示例
here . Python 代码可以是这样的:
#example.py
import example
print(example.run(["Lorem", "ipsum", "dolor", "sit", "amet"]))
example.cpp
的评论部分文件表明,可以使用 pybind11 数据类型,然后将它们转换为 C。但我怀疑纯 C 解决方案也可能是可能的。例如,参见 this attempt . 最佳答案
下面我重新格式化了 previous example code我使用 C++ 构造的地方,只使用 C 和 pybind11 构造。
#include <pybind11/pybind11.h>
#include <stdio.h>
#if PY_VERSION_HEX < 0x03000000
#define MyPyText_AsString PyString_AsString
#else
#define MyPyText_AsString PyUnicode_AsUTF8
#endif
namespace py = pybind11;
int run(py::object pyargv11) {
int argc = 0;
char** argv = NULL;
PyObject* pyargv = pyargv11.ptr();
if (PySequence_Check(pyargv)) {
Py_ssize_t sz = PySequence_Size(pyargv);
argc = (int)sz;
argv = (char**)malloc(sz * sizeof(char*));
for (Py_ssize_t i = 0; i < sz; ++i) {
PyObject* item = PySequence_GetItem(pyargv, i);
argv[i] = (char*)MyPyText_AsString(item);
Py_DECREF(item);
if (!argv[i] || PyErr_Occurred()) {
free(argv);
argv = nullptr;
break;
}
}
}
if (!argv) {
//fprintf(stderr, "argument is not a sequence of strings\n");
//return;
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError, "could not convert input to argv");
throw py::error_already_set();
}
for (int i = 0; i < argc; ++i)
fprintf(stderr, "%s\n", argv[i]);
free(argv);
return 0;
}
PYBIND11_MODULE(example, m) {
m.def("run", &run, "runs the example");
}
char*
基于,在 Python3 中,它们是基于 Unicode 的。因此下面的宏
MyPyText_AsString
这会根据 Python 版本改变行为,因为我们需要使用 C 风格的“char*”。
#if PY_VERSION_HEX < 0x03000000
#define MyPyText_AsString PyString_AsString
#else
#define MyPyText_AsString PyUnicode_AsUTF8
#endif
py::object
是 Python C-API 句柄对象上的细句柄;由于以下代码使用了 Python C-API,因此更容易处理底层
PyObject*
直接地。
void closed_func_wrap(py::object pyargv11) {
int argc = 0; // the length that we'll pass
char** argv = NULL; // array of pointers to the strings
// convert input list to C/C++ argc/argv :
PyObject* pyargv = pyargv11.ptr();
PyTuple
和
PyList
同时(虽然比直接检查这些类型要慢一点,但这会使代码更紧凑)。为了完全通用,这段代码还应该检查迭代器协议(protocol)(例如,对于生成器和可能拒绝 str 对象,但两者都不太可能。
if (PySequence_Check(pyargv)) {
Py_ssize_t sz = PySequence_Size(pyargv);
argc = (int)sz;
char*
(技术上是
const char*
,但这并不重要,因为我们将把它扔掉)。
argv = (char**)malloc(sz * sizeof(char*));
for (Py_ssize_t i = 0; i < sz; ++i) {
PyObject* item = PySequence_GetItem(pyargv, i);
const char*
的 Actor 阵容至
char*
这里原则上是安全的,但
argv[i]
的内容不得被其他函数修改。
argv
也是如此
main()
的参数,所以我假设是这样。
argv[i] = (char*)MyPyText_AsString(item);
PySequence_GetItem
的结果是一个新的引用,所以现在我们已经完成了它,删除它:
Py_DECREF(item);
if (!argv[i] || PyErr_Occurred()) {
free(argv);
NULL
稍后成功检查:
argv = nullptr;
break;
argv
所以我们保释:
if (!argv) {
fprintf(stderr, "argument is not a sequence of strings\n");
return;
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError, "could not convert input to argv");
throw py::error_already_set(); // by pybind11 convention.
argc
和
argv
,所以现在我们可以使用它们:
for (int i = 0; i < argc; ++i)
fprintf(stderr, "%s\n", argv[i]);
free(argv);
std::unique_ptr
因为如果抛出 C++ 异常(来自任何输入对象的自定义转换器),这会让生活变得更加轻松。 std::vector<char*> pv{pyargv.cast<std::vector<char*>>()};
之后 #include <pybind11/stl.h>
,但我发现这不起作用(即使它确实可以编译)。也没有使用 std::vector<std::string>
(也编译,但在运行时也失败)。 PyList_Check(pyargv11.ptr())
如果为真,则转换结果:
PyListObject* pylist = (PyListObject*)pyargv11.ptr()
.现在,如果您想使用
py::list
,您还可以使用以下代码:
#include <pybind11/pybind11.h>
#include <stdio.h>
#if PY_VERSION_HEX < 0x03000000
#define MyPyText_AsString PyString_AsString
#else
#define MyPyText_AsString PyUnicode_AsUTF8
#endif
namespace py = pybind11;
int run(py::list inlist) {
int argc = (int)inlist.size();
char** argv = (char**)malloc(argc * sizeof(char*));
for (int i = 0; i < argc; ++i)
argv[i] = (char*)MyPyText_AsString(inlist[i].ptr());
for (int i = 0; i < argc; ++i)
fprintf(stderr, "%s\n", argv[i]);
free(argv);
return 0;
}
PYBIND11_MODULE(example, m) {
m.def("run", &run, "runs the example");
}
关于python - 通过pybind11将字符串列表从python传递给C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60067092/
首先,感谢大家努力解决我的这个疑问。我正在转换一个最小的 C++ 项目以在 Python 中使用。这种努力背后的真正原因是为了速度。 我遇到了 PyBind,对它的功能以及他们提供的文档数量感到非常惊
我有以下类结构(我实际实现的简化示例): /* TestClass.hpp */ #pragma once template class CurRecTemplate { protected:
我有以下设置(1 个基类、1 个派生类、1 个容器)。容器采用 shared_ptr作为输入。 #include namespace py = pybind11; struct Base { };
我刚刚安装了 pybinding,我正在尝试运行该库文档中提出的第一个示例。 import pybinding as pb import numpy as np import matplotlib.p
我正在使用 pybind 包装一些 C++ 函数,然后在 Python 中使用它。我需要一些结构,但我不知道如何在 Python 中访问它的属性。我的结构没有只有方法的属性,所以我认为绑定(bind)
我使用以下命令创建了一个 miniconda 环境: conda create -n build_a_python_cpp_module xtensor-python -c conda-forge 激
为了更好地理解如何使用 pybind 库将参数从 Python 传递到 C++ 函数,我想构建一个小的虚拟/演示代码,我可以在其中接收 C++ 端的 Python 列表,将其转换为浮点指针对象,然后打
我正在尝试编译 Pybind11 C++ 中的模块它调用了几个头文件(.h)在上面。由于我有很多头文件,我决定做一个 Makefile ,没有问题,除了创建目标共享对象文件(s.o) .我需要这个共享
pybind 的新手 - 阅读文档,但我不了解如何将其应用于二维数组。 我有两个数组存储 3d 坐标 shape = (10,3) a = np.zeros(shape=(10,3)) b = np.
TL;博士 将 pybind11 绑定(bind)添加到工作中的 C++ DLL 项目允许我在 Python 中导入和使用生成的 DLL,但会破坏我使用 boost/dll 机制在 C++ 代码中使用
在 Pybind 中,可以通知 Python 关于函数的参数名称: m.def("add", &add, "A function which adds two numbers", py::arg(
当我运行 pip install .在我有 setup.py 的目录中。我正在使用 pybind11 为我的 C++ 项目构建一个 python 模块。 (同样,在 Windows 10 上) 我收到
我正在尝试使用 PyBind 在 C++ 中嵌入一些 Python 代码。大多数文档都是关于使用 C++ 扩展 Python,但我对嵌入感兴趣: 关于 http://pybind11.readthed
我正在尝试使用 pybind11 实现 C++ 到 python,并使用 pybind11-multiprocessing-hangs 。不同之处在于我想在c++中使用python对象并继续从c++调
我是一名优秀的程序员,十分优秀!