boost::python を使用して、C 構造体を C++ から numpy 配列として python に渡そうとしています。C 構造体を python に渡す簡単な方法があることは知っていますが、numpy 配列を使用する理由は、ソリューションがリフレクション モデルの一部であるため、データ型を文字列から動的に生成する必要があるためです。
python に渡す構造体を文字列としてシリアル化し、python で numpy.fromstring() を呼び出すと、numpy 配列に正常に変換されます。ただし、これを文字列に変換すると、データが参照によって python に渡される代わりにコピーされるため、これはあまり効率的ではありません。
例えば:
#include <boost/python.hpp>
using namespace boost::python;
struct MyRecord
{
uint32_t myInt;
char myString[4];
double myDouble;
};
class MyBaseClass
: public wrapper<MyBaseClass>
{
public:
void myCallback(const MyRecord& data)
{
object func = get_override("myCallback");
if (func) {
std::string dataStr(reinterpret_cast<const char*>(data), sizeof(data));
func(dataStr, "[('myInt','<u4'),('myString','|S4'),('myDouble','<f8')]");
}
}
};
BOOST_PYTHON_MODULE(example1)
{
class_<MyBaseClass>("MyBaseClass")
.def("myCallback", &MyBaseClass::myCallback);
}
#!/usr/bin/env python
import numpy
from example1 import MyBaseClass
class MyClass(MyBaseClass):
def myCallback(self, dataStr, dtypeStr):
dt = numpy.dtype(eval(dtypeStr))
data = numpy.fromstring(dataStr, dt)
print data # This is now a numpy array
私が本当にできるようにしたいのは、構造体を C++ で numpy 配列に変換し、参照によって直接 Python に渡すことです。
boost::python::numeric::array クラスを試してみましたが、C++ 型を numpy 配列に変換するのに問題があります。コンストラクターがスローしています:「TypeError: No to_python (by-value) converter found for C++ type: MyRecord」
いくつかのサンプルコードがあります:
#include <boost/python.hpp>
#include <boost/python/exec.hpp>
#include <boost/python/numeric.hpp>
using namespace boost::python;
struct MyRecord
{
uint32_t myInt;
char myString[4];
double myDouble;
};
class MyBaseClass
: public wrapper<MyBaseClass>
{
public:
void myCallback(const MyRecord& data)
{
object func = get_override("myCallback");
if (func) {
object dtype = exec("eval(\"[('myInt','<u4'),('myString','|S4'),('myDouble','<f8')]\")");
func(numeric::array(data, dtype)); // numeric::array throws
}
}
};
BOOST_PYTHON_MODULE(example2)
{
class_<MyBaseClass>("MyBaseClass")
.def("myCallback", &MyBaseClass::myCallback);
}
#!/usr/bin/env python
import numpy
from example2 import MyBaseClass
class MyClass(MyBaseClass):
def myCallback(self, data):
print data # This is a numpy array passed from C++
ありがとう、
ポール