使用 Boost Python 导出 const wchar_t* c++ 函数
Exporting const wchar_t* c++ function with Boost Python
我正在尝试公开一个 c++ 函数,该函数将 const wchar_t* 作为 python 中的参数。在我看来,const wchar_t* 不是一种受支持的输入类型,它会自动公开为 python 字符串,然后像普通的 const char* 一样自动转换。
是否可以添加某种自动正确的输入类型转换器?我知道我可以添加蹦床函数并自己进行 unicode 转换,但让它自动运行会方便得多。
我的提升版本是 1.52,我正在 64 位窗口上使用 python 2.7。
下面是显示该问题的简单 c++ 序列的示例代码:
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
void testWcharParam(const wchar_t* str) {
std::wcout << str << std::endl;
}
void testCharParam(const char* str) {
std::wcout << str << std::endl;
}
BOOST_PYTHON_MODULE(test)
{
def("testWcharParam", testWcharParam);
def("testCharParam", testCharParam);
}
在python中导入和运行时,我得到以下结果:
>>> import test
>>> test.testCharParam('test')
test
>>> test.testWcharParam('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
test.testWcharParam(str)
did not match C++ signature:
testWcharParam(wchar_t const * __ptr64)
>>>
出于某种原因,此处的字符串方法 http://www.boost.org/doc/libs/1_52_0/libs/python/doc/v2/faq.html#custom_string 不适用于原始wchar_t*。
编辑:添加了缺少的包含和平台信息。
编辑:在提升文档中添加了有关示例的说明
据我所知,没有办法从 Python 窄字符串 ( str
) 自动转换为 const wchar_t*
.
当 Boost.Python 尝试从 Python 对象转换时,它会在堆栈上分配内存以保存目标类型,然后尝试查找为目标类型注册的转换器。 在这种情况下,目标类型将为 const wchar_t*
。 一旦转换器指示PyObject
是有效的转换候选项,就会进行转换,初始化堆栈分配内存中的目标类型。 由于 Python/C API 仅支持在编码时创建新PyObject
,内存管理成为一个问题,因为 Boost.Python 只为wchar_t*
分配内存。
由于 Boost.Python 不提供在使用转换后的值后调用的后钩子,因此一个简单的折衷方案可能是将const wchar_t*
的参数类型更改为 std::wstring
。 当std::wstring
管理自己的内存时,Boost.Python 可以将PyObject
宽的字符串复制到其中。 此外,必要时,Boost.Python 会在转换为 std::wstring
的过程中将窄字符串编码为宽字符串。
示例代码:
#include <iostream>
#include <boost/python.hpp>
void testWcharParam(std::wstring str) { std::wcout << str << std::endl; }
void testCharParam(const char* str) { std::wcout << str << std::endl; }
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("testWcharParam", testWcharParam);
python::def("testCharParam", testCharParam);
}
用法:
>>> import example
>>> example.testCharParam('test 1')
test 1
>>> example.testWcharParam(u'test 2')
test 2
>>> example.testWcharParam('test 3')
test 3
我没有使用过Boost Python,但是Python 2中的wchar_t是一个Unicode字符串,所以请尝试:
>>> test.testWcharParam(u'test')
这是我最终使用的:
void* convert_to_wcstring(PyObject* obj)
{
if(PyString_Check(obj)) {
throw_error_already_set();
} else if(PyUnicode_Check(obj)) {
return PyUnicode_AsUnicode(obj);
}
throw_error_already_set();
return 0;
}
然后将其作为转换器添加到:
BOOST_PYTHON_MODULE(test)
{
converter::registry::insert(convert_to_wcstring, type_id<wchar_t>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
...
}
只要输入参数是 unicode 类型而不是普通字符串类型,这就可以工作。对于我的初始示例,它将给出以下结果:
# Works
test.testWcharParam(u'test')
# Doesn't work
test.testWcharParam('test')
就我而言,C++ API 比 python 更严格,这意味着我在那里清理输入字符串比在C++端要好得多。
感谢您的所有回答,您引导我朝着正确的方向前进,但我必须稍微调整一下才能解决我的确切用例。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗