Python类不能通过Boost.Python嵌入将C类识别为模块
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python类不能通过Boost.Python嵌入将C类识别为模块,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4069字,纯文字阅读大概需要6分钟。
内容图文
![Python类不能通过Boost.Python嵌入将C类识别为模块](/upload/InfoBanner/zyjiaocheng/818/f3d7448cfe56483baf3df97e9056727c.jpg)
Boost.Python v1.56中的以下示例显示了如何将Python 3.4.2解释器嵌入到您自己的应用程序中.不幸的是,在Windows 8.1下使用MSVC2013进行配置时,该示例无法正常使用.我还没有找到一个关于嵌入的完整示例,至少没有一个比10年左右更年轻.
运行它时收到以下错误:ImportError:’embedded_hello’不是内置模块
代码在这里:http://pastebin.com/shTtdxT8
任何暗示我可以做什么让这个运行?一般来说如何在Python中公开c类,反之亦然?
解决方法:
代码正在使用Python 2头配置进行编译.使用Python 3头配置进行编译时,boost/python/module_init.hpp会将embedded_hello模块的初始化函数声明为PyInit_embedded_hello而不是initembedded_hello.我强烈建议验证正确的头配置,并执行Boost.Python的干净构建,因为Boost.Python和使用库构建的模块需要使用相同的头配置.
此外,在将模块添加到内置表时,PyImport_AppendInittab()调用需要在Py_Initialize()之前进行.PyImport_AppendInittab()文档明确指出:
Add a single module to the existing table of built-in modules. … This should be called before
Py_Initialize()
.
Boost.Python使用BOOST_PYTHON_MODULE宏来定义Python模块.在模块的主体内,当前的scope是模块本身.因此,当通过类型包装器公开C类型时,例如当通过boost::python::class_将C类暴露给Python时,生成的Python类将位于BOOST_PYTHON_MODULE定义的模块中.
另一方面,在Python中声明的用户定义类型是第一类对象.从C角度来看,它们可以被视为工厂功能.因此,要在C中使用Python定义的类,需要获取类对象的句柄,然后通过调用类对象来实例化类的实例.
这是一个完整的最小示例,演示了如何嵌入Python 3解释器:
>导入直接构建到二进制文件中的模块(示例),并将基本C类(spam_wrap)公开给具有默认的虚函数/调度的Python(example.Spam).
>演示使用公开的Python类(example.Spam).
>从Python(example.PySpam)中公开的Python类(example.Spam)派生并使用生成的类.
#include <iostream>
#include <boost/python.hpp>
/// @brief Mockup Spam model.
struct spam
: boost::noncopyable
{
virtual ~spam() {};
virtual std::string hello() { return "Hello from C++"; }
};
//@ brief Mockup Spam wrapper.
struct spam_wrap
: spam,
boost::python::wrapper<spam>
{
virtual std::string hello()
{
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
return boost::python::call<std::string>(
this->get_override("hello").ptr());
#else
return this->get_override("hello")();
#endif
}
std::string default_hello() { return this->spam::hello(); }
};
/// @brief Python example module.
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
// Expose C++ spam_wrap as Python Spam class.
python::class_<spam_wrap, boost::noncopyable>("Spam")
.def("hello", &spam::hello, &spam_wrap::default_hello)
;
}
int main()
{
// Add example to built-in.
PyImport_AppendInittab("example", &PyInit_example);
// Start the interpreter.
Py_Initialize();
namespace python = boost::python;
try
{
python::object main = python::import("__main__");
python::object global = main.attr("__dict__");
// Execute Python code, using the example module.
exec(
"from example import Spam \n"
"spam = Spam() \n"
" \n"
"class PySpam(Spam): \n"
" def hello(self): \n"
" return 'Hello from Python'\n",
global, global);
/// Check the instance of the Python object using the C++ class.
// >>> spam_object = spam
python::object spam_object = global["spam"];
assert(python::extract<spam>(spam_object).check());
// >>> result = spam_object.hello()
python::object result = spam_object.attr("hello")();
// >>> print(result)
std::cout << python::extract<std::string>(result)() << std::endl;
// >>> assert("Hello from C++" == result)
assert("Hello from C++" == python::extract<std::string>(result)());
/// Create an instance using PySpam class. It too is a Python object.
// >>> py_spam_type = PySpam
python::object py_spam_type = global["PySpam"];
// >>> py_spam_object = py_spam_type()
python::object py_spam_object = py_spam_type();
// >>> result = py_spam_object()
result = py_spam_object.attr("hello")();
// >>> print(result)
std::cout << python::extract<std::string>(result)() << std::endl;
// >>> assert("Hello from Python" == result)
assert("Hello from Python" == python::extract<std::string>(result)());
}
catch (const python::error_already_set&)
{
PyErr_Print();
}
}
该程序应该运行完成而不会出现错误,从而产生以下输出:
Hello from C++
Hello from Python
内容总结
以上是互联网集市为您收集整理的Python类不能通过Boost.Python嵌入将C类识别为模块全部内容,希望文章能够帮你解决Python类不能通过Boost.Python嵌入将C类识别为模块所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。