我有一个库创建对象(类A的实例)并将它们传递给python程序,该程序应该能够调用它们的方法.
基本上我有C++类实例,我想从python中使用它们.有时,该对象应该传递回C++进行一些操作.
我创建了以下包装器文件(假设该New函数在C++代码中的某处调用):
#include <boost/python.hpp>
#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace boost::python;
int calls = 0;
struct A
{
int f() { return calls++; }
~A() { std::cout << "destroyed\n"; }
};
shared_ptr<A> existing_instance;
void New() { existing_instance = shared_ptr<A>( new A() ); }
int Count( shared_ptr<A> a ) { return a.use_count(); }
BOOST_PYTHON_MODULE(libp)
{
class_<A>("A")
.def("f", &A::f)
;
def("Count", &Count);
register_ptr_to_python< shared_ptr<A> >();
}
Run Code Online (Sandbox Code Playgroud)
代码缺少python获取的部分existing_instance.我没有粘贴它,但我只是说我为此目的使用回调机制.
这段代码有效,但我有几个问题:
在Count函数(以及所有其他C++操作函数中)可以这样传递a或者更好地做类似的事情const shared_ptr<A>&吗?在我在python …
我有一个带有此签名的python函数:
def post_message(self, message, *args, **kwargs):
Run Code Online (Sandbox Code Playgroud)
我想从c ++调用函数并传递给它一些kwargs.调用函数不是问题.知道如何通过kwargs是.这是一个非工作的释义样本:
std::string message("aMessage");
boost::python::list arguments;
arguments.append("1");
boost::python::dict options;
options["source"] = "cpp";
boost::python::object python_func = get_python_func_of_wrapped_object()
python_func(message, arguments, options)
Run Code Online (Sandbox Code Playgroud)
当我运用这段代码时,在pdb中我得到了(这不是我想要的):
messsage = aMessage
args = (['1'], {'source': 'cpp'})
kwargs = {}
Run Code Online (Sandbox Code Playgroud)
你如何在我的例子中传递**kwargs字典中的选项?
我看过一篇建议使用**选项语法的帖子(这有多酷!):
python_func(message, arguments, **options)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这导致了
TypeError: No to_python (by-value) converter found for C++ type: class boost::python::detail::kwds_proxy
Run Code Online (Sandbox Code Playgroud)
感谢您提供任何帮助.
我有使用两个64位浮点数(两双类模拟128bit的浮筒的自定义浮点数据类型dd_real从QD库).从C++我想导出一个ndarray到python.我已经知道如何为64位浮点数做这个,但是对于双倍的我需要指定我自己的自定义dtype.怎么做?
注意:numpy有自己的128位浮点数(np.float128),遗憾的是它映射到long doubleC/C++,它只是一个存储在128位(在我所有平台上)的80位浮点数.
实际上,应该能够以与numpy导出np.float128(我只是不知道如何完成)相同的方式完成此操作,唯一的区别是它dd_real在C++端使用而不是long double.
如果这有帮助,我已经将C++类型导出dd_real到python使用boost::python也许这可以以某种方式重用.
到目前为止,我能够研究以下内容
我一直在将python嵌入到c ++中,我想知道是否有办法找到boost :: python :: object的类型,这是执行python模块函数后的结果.我的代码是这样的:
boost::python::object module_ = boost::python::import("..libName");
boost::python::object result_ = module_.attr("..functionName")(arg1, arg2,...);
//suppose if the result is int,
int a_ = boost::python::extract<int>(result_);
Run Code Online (Sandbox Code Playgroud)
从上面的代码片段中,我想知道的是,在提取结果之前是否有办法找到结果的类型.在上面的代码中,result_可能是任何类型,如list,tuple ......
我正在使用boost :: python将一些python代码嵌入到应用程序中.我能够正确评估print语句或其他表达式,但是当我尝试导入模块时,它不是导入而应用程序正在退出.此外,嵌入式代码中的globals()函数调用也会产生运行时错误.
#include <boost/python.hpp>
using namespace boost;
using namespace boost::python;
using namespace boost::python::api;
int main(void) {
Py_Initialize();
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
main_namespace["urllib2"] = import("urllib2");
object ignored = exec(
"print 'time'\n", main_namespace);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我尝试使用boost import函数导入urllib2,这会编译并正常运行,但是使用以下exec语句,它会出错.
object ignored = exec(
"print urllib2\n"
"print 'time'\n", main_namespace);
Run Code Online (Sandbox Code Playgroud)
或者当我删除boost导入函数并从嵌入代码中进行导入时,它会出错.我尝试使用try:except:block但是这也不起作用.这是因为C++应用程序无法找到urllib2 py模块的位置或什么?有没有办法在尝试导入之前设置模块的路径?
这是为内部使用而构建的,因此可以接受一些路径的硬编码.
编辑:更多信息:
这就是发生的事情.我做了一次尝试..捕获并在有异常时调用PyErr_Print(),并且在模块导入甚至函数调用时始终将其作为错误.错误信息:
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)
谁能想到任何理由?
我正在使用Boost Python库来创建我的C++代码的python扩展.我希望能够从python中调用下面显示的C++代码中的'greet'函数:
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
Run Code Online (Sandbox Code Playgroud)
和python代码:
import hello_ext
print hello_ext.greet()
Run Code Online (Sandbox Code Playgroud)
我已经设法使用bjam(hello_ext.pyd生成并且它工作得很好),但现在我想使用Visual Studio 2008构建它.一个hello.dll被构建(但是hello_ext.dll也没有.pyd).在调用我的python代码后,我收到一个错误:
ImportError:没有名为hello_ext的模块.
将hello.dll重命名为hello.pyd或hello_ext.pyd后,我得到另一个ImportError:Dll加载失败
如何使用VS 2008构建正确的.pyd文件?
我是新手来提升python.我必须首先在cpp代码中初始化一个cpp类实例,然后将这个cpp实例传递给python代码,使用python类实例来调用它(cpp实例).我已经尝试过Python/C API方法但是失败了,所以我想知道如何将c ++类实例传递给python类.
以下是我的代码,改进了boost python演示.
在main.cpp中
#include <python2.6/Python.h>
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
using namespace std;
class World
{
private:
string name;
public:
void set(string name)
{
this->name = name;
}
void greet()
{
cout << "hello, I am " << name << endl;
}
};
typedef boost::shared_ptr< World > world_ptr;
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
register_ptr_to_python<world_ptr>();
};
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
world_ptr worldObjectPtr (new World);
worldObjectPtr->set("C++!");
try
{
inithello();
PyObject* pModule …Run Code Online (Sandbox Code Playgroud) 我有第三方C++库,其中一些类方法使用原始字节缓冲区.我不太确定如何处理Boost :: Python.
C++库头类似于:
class CSomeClass
{
public:
int load( unsigned char *& pInBufferData, int & iInBufferSize );
int save( unsigned char *& pOutBufferData, int & iOutBufferSize );
}
Run Code Online (Sandbox Code Playgroud)
坚持使用Boost :: Python代码......
class_<CSomeClass>("CSomeClass", init<>())
.def("load", &CSomeClass::load, (args(/* what do I put here??? */)))
.def("save", &CSomeClass::save, (args(/* what do I put here??? */)))
Run Code Online (Sandbox Code Playgroud)
如何将这些原始缓冲区包装在Python中作为原始字符串公开?
我想使用Boost.Python将以下C++函数公开给Python:
int* test1() {
return new int(42);
}
// Now exposing the function with Boost.Python
BOOST_PYTHON_MODULE(libtest1)
{
using namespace boost::python;
def("test1", test1);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译这个库时,由于(我的猜测)Boost.Python不知道如何将int*转换为PyObject而发生错误.
我认为需要做的是定义转换结构,如下所示:
template<class T>
struct int_ptr_to_python
{
static PyObject* convert(int* i_ptr)
{
return i_ptr;
}
};
Run Code Online (Sandbox Code Playgroud)
并将其传递给BOOST_PYTHON_MODULE声明:
BOOST_PYTHON_MODULE(libtest1)
{
using namespace boost::python;
def("test1", test1);
to_python_converter<int*, int_ptr_to_python<int*> >();
}
Run Code Online (Sandbox Code Playgroud)
但它也行不通.而且我找不到有关如何处理返回指针的函数的任何信息.
有人可以帮忙吗?
为了以一种实际工作方式向Python公开C++异常,你必须编写如下内容:
std::string scope = py::extract<std::string>(py::scope().attr("__name__"));
std::string full_name = scope + "." + name;
PyObject* exc_type = PyErr_NewException(&full_name[0], PyExc_RuntimeError, 0);
// ...
Run Code Online (Sandbox Code Playgroud)
但这似乎与Boost.Python中的任何其他东西都没有相互影响.如果我想暴露:
struct Error { int code; };
Run Code Online (Sandbox Code Playgroud)
我可以写:
py::class_<Error>("Error", py::no_init)
.def_readonly("code", &Error::code)
;
Run Code Online (Sandbox Code Playgroud)
如何将类绑定Error与异常创建结合起来PyErr_NewException?基本上,我希望throw Error{42}并以明显的方式从Python中完成这项工作:我可以抓住Error或者RuntimeError拥有这项工作,我可以抓住AssertionError(或者类似的)并且没有捕获Error也不会抛出SystemError.