(注:我已经在pybind11 的 GitHub上问过这个问题。为更广泛的受众提供支持。也标记 boost.python 以防有人有洞察力,但问题是如何使用 pybind11 做到这一点)
环境:Ubuntu 18.04、GCC 7.4.0、Python 3.6.9、pybind11 2.4.3
假设我们想用 pybind11 包装一个共享库libfoo.so,导出一个基类Foo(即,使用 vtable,在本例中只是一个虚拟析构函数)。
如果我们导出整个类(即添加visibility("default")到整个类),那么一切都会按预期进行:
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
add_subdirectory(pybind11)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES CXX_VISIBILITY_PRESET hidden)
pybind11_add_module(pyfoo pyfoo.cpp)
target_link_libraries(pyfoo PRIVATE foo)
Run Code Online (Sandbox Code Playgroud)
foo.h
#define FOO_API __attribute__((visibility("default")))
class FOO_API Foo { public: virtual ~Foo(); };
Run Code Online (Sandbox Code Playgroud)
foo.cpp
#include "foo.h"
Foo::~Foo() {}
Run Code Online (Sandbox Code Playgroud)
pyfoo.cpp
#include <pybind11/pybind11.h>
#include "foo.h"
PYBIND11_MODULE(pyfoo, m) {
pybind11::class_<Foo>(m, "Foo")
.def(pybind11::init<>());
}
Run Code Online (Sandbox Code Playgroud)
测试.py
import pyfoo
f = pyfoo.Foo()
print("Test succeeded")
Run Code Online (Sandbox Code Playgroud)
构建并运行: …
我想在 Python 中为我的 C++ 代码启用类型提示。
using boost::python;
BOOST_PYTHON_MODULE(foo)
{
docstring_options doc_options;
doc_options.disable_all();
doc_options.enable_user_defined();
class_<Bar>("Bar", init<>(), "Bar class" )
.def("foobar", &Bar::foobar, (arg("name")), "foobar(name: str) -> None");
}
Run Code Online (Sandbox Code Playgroud)
但在 python 中,我只能在缺少类型提示的情况下得到这个。有什么办法可以保留类型提示吗?
using boost::python;
BOOST_PYTHON_MODULE(foo)
{
docstring_options doc_options;
doc_options.disable_all();
doc_options.enable_user_defined();
class_<Bar>("Bar", init<>(), "Bar class" )
.def("foobar", &Bar::foobar, (arg("name")), "foobar(name: str) -> None");
}
Run Code Online (Sandbox Code Playgroud) 我编写了一些生成std :: vector的C++代码.
我还有一个操作一些数据的python脚本,现在,我正在这样声明(如下).
import numpy
x = numpy.random.randn(1000)
y = numpy.random.randn(1000)
Run Code Online (Sandbox Code Playgroud)
我可以运行脚本.从我的C++代码:
using namespace boost::python;
try{
Py_Initialize();
object main = import("__main__");
object global(main.attr("__dict__"));
object result = exec_file("scatterPlot.py", global, global);
Py_Finalize();
}
catch(error_already_set){
PyErr_Print();
}
return;
Run Code Online (Sandbox Code Playgroud)
我不知道如何将我的C++数据转换为python.我有很多,但似乎没有任何确定性.
我有我的C++
BOOST_PYTHON_MODULE(vector_indexing_suite_ext){
boost::python::class_<std::vector<double> >("PyVec")
.def(boost::python::vector_indexing_suite<std::vector<double> >());
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但据我所知,它只为我的python脚本提供了一个类"PyVec",但不提供我需要的数据.我错了吗?
我还看到其他人在python邮件列表中使用boost :: shared_ptr.
我也发现了这个例子但发现它令人困惑.
我可以想到几种方法
boost::python::exec_file方法boost_indexing_suite_extboost::shared_ptr哪种方法最容易开始?我觉得没办法.
这里有一些我看过的链接: 来自 python网站 的boost网站上的另一个邮件列表线程
更新:
这适用于传递int给我的python代码,如下所示
int main(){
int five_squared=0;
int a …Run Code Online (Sandbox Code Playgroud) 假设:
using namespace boost::python;
void myClass::test(numeric::array& arrayParam) {
const tuple &shape = extract<tuple>(arrayParam.attr("shape"));
}
Run Code Online (Sandbox Code Playgroud)
我想将它转换为int并打印例如.我试过int x = shape[0];但它给了我一个"无法将'boost :: python :: api :: const_object_item'转换为初始化'消息中的'int'.
如何从std :: function构造boost :: python ::对象?
我brew install boost在运行Lion的Mac上安装了Boost with homebrew(),目的是使用现有的C++程序扩展python.现在我不能按照起始指南,因为1 - 我没有在我的系统中安装'bjam'和2 - 我没有在任何地方看到examples文件夹.我的问题是:如何在不使用'bjam'的情况下将c ++ - python链接到这个自制软件安装?是否有一些我应该使用的替代方法或我在这里缺少的东西?
我必须犯一些明显的错误,但经过数小时的战斗,我无法取得进一步的进展:
升级到(所有三个升压1.54,CMake的2.8.12和Python 2.7.5后小幅早期次要版本),我的Python绑定项目在调试配置不再联系(他们释放联接罚款).我正在使用VS 2012构建.在更新之前一切正常.
我用标准的方式构建了Boost:bootstrap.bat接下来b2 address-model=64 toolset=msvc-11.0.我的系统有一个Python 2.7安装,由b2选择:
notice: [python-cfg] Configuring python...
notice: [python-cfg] Registry indicates Python 2.7 installed at "C:\Python27\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Python27\python.exe" 2>&1'
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...requested configuration matched!
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg] interpreter command: "python"
notice: [python-cfg] include …Run Code Online (Sandbox Code Playgroud) 我有一个带有成员函数的C++类,它使用unsigned char*buffer和unsigned int length作为参数并对它们进行操作.我用Boost :: Python包装了这个类,并希望从Python脚本中将预先填充的缓冲区传递给该类.Python端缓冲区是用struct.pack创建的.我无法弄清楚如何使参数类型匹配并继续获取Boost.Python.ArgumentError.
#ifndef EXAMPLECLASS_H_
#define EXAMPLECLASS_H_
#include <cstdio>
class ExampleClass
{
public:
ExampleClass() {}
virtual ~ExampleClass() {}
void printBuffer(unsigned char* buffer, unsigned int length)
{
for (unsigned int i = 0; i < length; ++i)
{
printf("%c", buffer[i]);
}
printf("\n");
}
};
#endif
Run Code Online (Sandbox Code Playgroud)
#include "Example.h"
int main(int argc, char** argv)
{
unsigned char buf[4];
buf[0] = 0x41;
buf[1] = 0x42;
buf[2] = 0x43;
buf[3] = 0x44;
ExampleClass e;
e.printBuffer(buf, 4);
return 0;
} …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试在Windows(使用英特尔编译器)上构建一个在UNIX上使用CMake编译得非常好的大项目.这是我的问题的简单示例.
使用Boost.Python运行以下简单的代码示例:
#include <iostream>
#include <Python.h>
#include <boost/python.hpp>
int main()
{
std::string python_home = "C:\\softs\\python\\2.7.9\\64";
char* python_home_char = new char[python_home.length() + 1];
strcpy(python_home_char, python_home.c_str());
Py_SetPythonHome(python_home_char);
Py_Initialize();
boost::python::object pyobj_main = boost::python::import("__main__");
boost::python::object glob = pyobj_main.attr("__dict__");
boost::python::exec("print \"Hello from Python\"", glob, glob);
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
执行代码时出现以下错误消息:
程序无法启动,因为您的计算机缺少boost_python-iw-mt-1_57.dll.尝试重新安装该程序以解决此问题.
请注意,如果删除boost::python::***代码末尾的3行,我没有错误.另外,如果我使用Boost.Thread编译以下示例,我没有任何错误(在我看来,它也使用库(不是标题),是不是?):
#include <iostream>
#include <boost/thread.hpp>
boost::mutex mutex_hello;
void hello(unsigned long int thread_number)
{
boost::mutex::scoped_lock lock_hello(mutex_hello);
std::cout << "Hello from thread " << thread_number << std::endl;
}
int main()
{
boost::thread_group group;
for(unsigned …Run Code Online (Sandbox Code Playgroud) 我需要加快一些在NumPy数组上工作的算法.他们将使用std::vector一些更先进的STL数据结构.
我已将我的选择范围缩小到Cython(现在包装大多数STL容器)和Boost.Python(现在内置支持NumPy).
根据我作为程序员的经验,我知道有时需要几个月的时间来使用框架来揭示其隐藏的问题(因为它们很少被其门徒用作谈话点),所以你的帮助可能会为我节省大量时间.
在Cython和Boost.Python中扩展NumPy的相对优缺点是什么?