我正在使用外部程序来计算用C++编写并与python通过接口的矩阵boost::python.我想把这个C数组传递给numpy,根据作者的说法,这个能力已经用numpy实现了obj.__array_interface__.如果我在python脚本中调用它并将C++对象分配给X我,我将获得以下内容:
print X
#<sprint.Matrix object at 0x107c5c320>
print X.__array_interface__
#<bound method Matrix.__array_interface__ of <sprint.Matrix object at 0x107c5c320>>
print X.__array_interface__()
#{'shape': (5, 5), 'data': (4416696960, True), 'typestr': '<f8'}
print np.array(X)
#Traceback (most recent call last):
# File "<string>", line 96, in <module>
#ValueError: Invalid __array_interface__ value, must be a dict
Run Code Online (Sandbox Code Playgroud)
从我有限的理解,我相信问题X.__array_interface__是没有实际上没有返回任何东西().有没有办法np.array明确地传递这些参数或解决此问题.
我真的很擅长混合C++和python,如果这没有意义,或者我需要在任何部分阐述让我知道!
我试图让 Boost Python 要求参数由调用者命名。
由于 Python 3 实现了PEP 3102,我可以在纯 Python 中轻松做到这一点:
def foo(*, name=None, age=None):
print("%s is %d years" % (name, age))
Run Code Online (Sandbox Code Playgroud)
上面的意思是:
foo(name="Joe", age=33) # works
foo(age=33, name="Joe") # works
foo("Joe", 33) # raises TypeError
Run Code Online (Sandbox Code Playgroud)
然而,这在 Boost Python 中并不是直接的。以下甚至不接近:
#include <stdio.h>
#include <string>
#include <boost/python.hpp>
#include <boost/python/def.hpp>
void foo(const std::string& name, int age)
{
printf("%s is %d years\n", name.c_str(), age);
}
BOOST_PYTHON_MODULE(hello)
{
using namespace boost::python;
def("foo", foo, (arg("name"), arg("age")));
}
Run Code Online (Sandbox Code Playgroud)
虽然这适用于命名参数,但它们不是必需的,所以我仍然可以做foo("Joe", 33).
我试过了:
我有一个很小的 Python 脚本,它(在我看来)threading.Thread.start()由于它不会立即返回而导致行为出乎意料。
在一个线程中,我想从一个boost::python不会立即返回的基于对象调用一个方法。
为此,我像这样包装对象/方法:
import threading
import time
import my_boostpython_lib
my_cpp_object = my_boostpython_lib.my_cpp_class()
def some_fn():
# has to be here - otherwise .start() does not return
# time.sleep(1)
my_cpp_object.non_terminating_fn() # blocks
print("%x: 1" % threading.get_ident())
threading.Thread(target=some_fn).start()
print("%x: 2" % threading.get_ident()) # will not always be called!!
Run Code Online (Sandbox Code Playgroud)
只要我在 my_cpp_object.non_terminating_fn(). 如果我不这样做,.start()将像.run()直接调用一样阻塞。
在调用boost::python函数之前只打印一行是不够的,但是例如打印两行或调用time.sleep()使start()按预期立即返回。
你能解释一下这种行为吗?我将如何避免这种情况(除了sleep()在调用boost::python函数之前调用)?
我试图用C++构建一个Python模块,将2D矢量转换为Numpy 2D数组.这里有什么不对的 - 可能是PyObject*中的boost python对象需要进行一些转换?
boost::python::object build_day(int year, int day) {
PyObject* arr;
const int HEIGHT = 5;
const int WIDTH = 5;
std::vector<std::vector<float> > array(WIDTH, std::vector<float>(HEIGHT));
npy_intp dims[2] = {WIDTH, HEIGHT};
arr = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, &array);
return arr;
}
BOOST_PYTHON_MODULE(sumpar) {
using namespace boost::python;
def("build_day", build_day, args("year", "day"));
}
Run Code Online (Sandbox Code Playgroud) 我成功地能够加载python脚本文件并boost::python在C++应用程序中调用函数.
在boost python EmbeddingPython wiki中,有一个关于如何加载python模块的提示.
namespace bp = boost::python;
bp::object import(const std::string& module, const std::string& path, bp::object& globals)
{
bp::dict locals;
locals["module_name"] = module;
locals["path"] = path;
bp::exec("import imp\n"
"new_module = imp.load_module(module_name, open(path), path, ('py', 'U', imp.PY_SOURCE))\n",
globals,
locals);
return locals["new_module"];
}
Run Code Online (Sandbox Code Playgroud)
我可以成功使用它来导入python模块(test.py)
int main()
{
Py_Initialize();
bp::object main = bp::import("__main__");
bp::object globals = main.attr("__dict__");
bp::object module = import("test", "test.py", globals);
bp::object run = module.attr("run");
run();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用hello-world test.py脚本运行上面的代码可以正常工作:
test.py: …
我已经成功地按照这个例子来了解如何连接 C++ 和 python。当我使用给定的Makefile. 当我尝试使用cmake它时,效果不佳。
C++代码:
#include <boost/python.hpp>
#include <iostream>
extern "C"
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
int main(){
std::cout<<greet()<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
生成文件:
# location of the Python header files
PYTHON_VERSION = 27
PYTHON_DOT_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_DOT_VERSION)
# location of the Boost Python include files and library
BOOST_INC = /usr/include
BOOST_LIB = /usr/lib/x86_64-linux-gnu/
# compile mesh classes
TARGET = hello_ext …Run Code Online (Sandbox Code Playgroud) 我都boost和boost-python安装通过brew我的MacOS 10.12塞拉利昂.但是,boost-python似乎并未认为其依赖项boost已安装:
$ brew info boost
boost: stable 1.68.0 (bottled), HEAD
Collection of portable C++ source libraries
https://www.boost.org/
/usr/local/Cellar/boost/1.65.1 (12,679 files, 401.2MB)
Poured from bottle on 2017-10-28 at 09:19:27
/usr/local/Cellar/boost/1.67.0_1 (13,506 files, 447.7MB) *
Poured from bottle on 2018-05-18 at 03:58:16
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/boost.rb
==> Dependencies
Optional: icu4c ?
==> Options
--with-icu4c
Build regexp engine with icu support
--without-single
Disable building single-threading variant
--without-static
Disable building static library variant
--HEAD
Install …Run Code Online (Sandbox Code Playgroud) 我正在尝试在一个项目中使用 Boost Python。我已在 Windows 10 上下载并构建版本 1.70,并且正在使用 Visual Studio Code。当尝试使用以下行将 boost 导入到我的 c++ 项目中时:
#include <boost\python.hpp>
Run Code Online (Sandbox Code Playgroud)
,我收到以下错误:
cannot open source file "pyconfig.h" (dependency of "boost\python.hpp")
Run Code Online (Sandbox Code Playgroud)
我研究过类似的问题,我发现的主要解决方案是编辑 user-config.jam 以包含我的 python 安装位置。我已经这样做了,user-config.jam 中的行如下所示:
using python : 3.7 : C:\Users\broke\AppData\Local\Programs\Python\Python37 ;
Run Code Online (Sandbox Code Playgroud)
添加这一行后,我重建了 Boost Python。这对解决这个问题没有任何帮助。我非常感谢有关此事的帮助。谢谢。
我有一个使用boost python导出到Python的方法,它将boost :: function作为参数.
从我所读的boost :: python应该支持boost :: function没有太大惊小怪,但是当我尝试用python方法调用该函数时它给了我这个错误
Boost.Python.ArgumentError: Python argument types in
Class.createTimer(Class, int, method, bool)
did not match C++ signature:
createTimer(class Class {lvalue}, unsigned long interval,
class boost::function<bool _cdecl(void)> function, bool recurring=False)
Run Code Online (Sandbox Code Playgroud)
我用这段代码从python中调用它
self.__class.createTimer( 3, test.timerFunc, False )
Run Code Online (Sandbox Code Playgroud)
在C++中,它被定义为
boost::int32_t createTimer( boost::uint32_t interval, boost::function< bool() > function, bool recurring = false );
Run Code Online (Sandbox Code Playgroud)
这里的目标是一个计时器类,我可以做类似的事情
class->createTimer( 3, boost::bind( &funcWithArgs, arg1, arg2 ) )
Run Code Online (Sandbox Code Playgroud)
创建一个执行funcWithArgs的计时器.感谢boost bind,这几乎适用于任何函数或方法.
那么我需要使用什么语法让boost :: python接受我的python函数作为boost :: function?
我花了两天的时间尝试从Boost.Python中启动示例,其中包含"ImportError:DLL加载失败:无法找到指定的模块"错误,同时尝试加载已编译的(使用bjam)pyd模块.我使用的是Windows 7 x64,Python 2.7 x64和Boost 1.47.我在StackOverflow和其他网站上跟进了不同的答案.全新安装(Python 32和64位,Boost预编译),手动Boost的库构建,DLL检查与依赖步行器等等,没有运气.我注册分享解决方案,这在这里工作,我希望可以帮助某人,努力解决同样的错误;)