Boost.Python :C++模板类型匹配的嵌套命名空间
Boost.Python : nested namespace matching C++ template types
尝试使用 Boost.Python 将 python numpy 数组传递给C++,在C++中处理它们,并将进程结果返回给 python:由于数组的类型在C++端模板化,它应该匹配 python 端的嵌套命名空间。
尽管进行了许多测试/谷歌搜索,但尚未找到解决方案。
错误:"Boost.Python.ArgumentError python参数类型与C++签名不匹配":任何线索?...
>> more dummy.hpp dummy.cpp dummy.py
::::::::::::::
dummy.hpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <iostream>
namespace bp = boost::python;
namespace np = boost::python::numpy;
template<typename FD>
class dummy {
public:
dummy() {
Py_Initialize();
np::initialize();
mean = 0.;
};
int doStuffs(np::ndarray & A) {
int szA = A.shape(0);
FD * ptrA = reinterpret_cast<FD*>(A.get_data());
for (int i = 0; i < szA; ++i) {
std::cout << "dummy::doStuffs - " << i << " : " << ptrA[i] << std::endl;
mean += ptrA[i];
}
mean /= szA;
std::cout << "dummy::doStuffs, mean " << mean << std::endl;
return 0;
};
FD mean;
};
template<typename FD>
void exportDummy(std::string const & nested) {
std::string module = "dummy." + nested;
bp::object pyModule(bp::handle<>(bp::borrowed(PyImport_AddModule(module.c_str()))));
bp::scope().attr(nested.c_str()) = pyModule;
bp::scope pyScope = pyModule;
bp::class_<dummy<FD>, boost::noncopyable>(nested.c_str())
.def ("doStuffs", &dummy<FD>::doStuffs)
.def_readonly ("mean", &dummy<FD>::mean);
};
::::::::::::::
dummy.cpp
::::::::::::::
#include <boost/python.hpp>
#include <dummy.hpp>
namespace bp = boost::python;
BOOST_PYTHON_MODULE(dummy)
{
// Specify that this module is actually a package.
bp::object package = bp::scope();
package.attr("__path__") = "dummy"; // Setting the __path__ attribute on the module to the name of the module.
// Create modules.
exportDummy<float>("float");
}
::::::::::::::
dummy.py
::::::::::::::
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
from scipy import sparse
n = 4
one = np.array([ 1]*n)
data = np.array([2.*one, -1.*one, -1.*one])
diags = np.array([0, 1, -1])
A = sparse.spdiags(data, diags, n, n)
print("python A ", A.toarray())
import dummy
dummyFloat = dummy.float.float()
dummyFloat.doStuffs(A)
print("python mean", dummyFloat.mean)
我得到:
>> make
g++ -I/usr/include/python2.7 -I. -fPIC -shared -o dummy.so dummy.cpp -lboost_numpy -lboost_python -lpython2.7
>> python dummy.py
python A [[ 2. -1. 0. 0.]
[-1. 2. -1. 0.]
[ 0. -1. 2. -1.]
[ 0. 0. -1. 2.]]
Traceback (most recent call last):
File "dummy.py", line 17, in <module>
dummyFloat.doStuffs(A)
Boost.Python.ArgumentError: Python argument types in
float.doStuffs(float, dia_matrix)
did not match C++ signature:
doStuffs(dummy<float> {lvalue}, boost::python::numpy::ndarray {lvalue})
找到解决方案!
>> more dummy.cpp dummy.hpp dummy.py
::::::::::::::
dummy.cpp
::::::::::::::
#include <boost/python.hpp>
#include <complex>
#include <dummy.hpp>
namespace bp = boost::python;
BOOST_PYTHON_MODULE(dummy)
{
bp::object package = bp::scope();
package.attr("__path__") = "dummy";
exportDummy<float>("float");
exportDummy<complex<float>>("complexFloat");
}
::::::::::::::
dummy.hpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <iostream>
namespace bp = boost::python;
namespace np = boost::python::numpy;
using namespace std;
template<typename FD>
class dummy {
public:
dummy() {
Py_Initialize();
np::initialize();
mean = 0.;
};
int doStuffs(np::ndarray & A) {
int szA = A.shape(0);
FD * ptrA = reinterpret_cast<FD*>(A.get_data());
for (int i = 0; i < szA; ++i) {
std::cout << "C++ - dummy::doStuffs - " << i << " : " << ptrA[i] << std::endl;
mean += ptrA[i];
}
mean /= szA;
return 0;
};
FD mean;
};
template<typename FD>
void exportDummy(std::string const & nested) {
std::string module = "dummy";
bp::object pyModule(bp::handle<>(bp::borrowed(PyImport_AddModule(module.c_str()))));
bp::scope pyScope = pyModule;
pyScope.attr(nested.c_str()) = bp::class_<dummy<FD>, boost::noncopyable>(nested.c_str())
.def ("doStuffs", &dummy<FD>::doStuffs)
.def_readonly("mean", &dummy<FD>::mean)
;
};
::::::::::::::
dummy.py
::::::::::::::
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import dummy
A = np.array([1, 2, 3], dtype='float32')
print("python A ", A)
df = dummy.float()
df.doStuffs(A)
print("python mean", df.mean)
A = np.array([1+2j, 3+4j, 5+6j], dtype='complex64')
print("python A ", A)
dcf = dummy.complexFloat()
dcf.doStuffs(A)
print("python mean", dcf.mean)
我得到:
>> make
g++ -I/usr/include/python2.7 -I. -fPIC -shared -o dummy.so dummy.cpp -lboost_numpy -lboost_python -lpython2.7
>> python dummy.py
python A [1. 2. 3.]
C++ - dummy::doStuffs - 0 : 1
C++ - dummy::doStuffs - 1 : 2
C++ - dummy::doStuffs - 2 : 3
python mean 2.0
python A [1.+2.j 3.+4.j 5.+6.j]
C++ - dummy::doStuffs - 0 : (1,2)
C++ - dummy::doStuffs - 1 : (3,4)
C++ - dummy::doStuffs - 2 : (5,6)
python mean (3+4j)
相关文章:
- 嵌套命名空间的"using"指令,但需要命名内部命名空间
- Boost.Python :C++模板类型匹配的嵌套命名空间
- 使用 astyle 在一行上格式化C++中的嵌套命名空间
- 为什么C 允许具有相同名称的嵌套名称空间
- 用于更简洁代码的嵌套命名空间
- 在嵌套名称空间范围中使用名称空间的正确方法
- 是否可以避免在前向声明中使用嵌套命名空间?
- 尽管包含头文件,但仍找不到嵌套命名空间
- C 11无法解析嵌套名称空间
- 在嵌套命名空间中向前声明
- 如何让代码存在于两个或多个非嵌套命名空间的范围内
- 嵌套命名空间:从内部命名空间访问值
- 如何在不同的文件中使用嵌套命名空间
- 带有嵌套名称空间的Bison和C++不会为我编译
- 嵌套名称空间是如何工作的
- 具有嵌套命名空间内的友元函数的模板类
- 在嵌套命名空间中重载流操作符
- 使方法成为嵌套命名空间中的好友
- C++ ADL 在具有模板函数的嵌套命名空间中
- 使用嵌套命名空间声明"using namespace"时出错 ( "namespace xxx::yyy not allowed in using-declaration" )