|
@@ -0,0 +1,253 @@
|
|
|
+#include <boost/python.hpp>
|
|
|
+#include <boost/python/numpy.hpp>
|
|
|
+
|
|
|
+#include <boost/thread.hpp>
|
|
|
+
|
|
|
+#include <boost/signals2.hpp>
|
|
|
+
|
|
|
+#include <iostream>
|
|
|
+#include <thread>
|
|
|
+#include <chrono>
|
|
|
+
|
|
|
+#include <Python.h>
|
|
|
+#include <string>
|
|
|
+#include <mutex>
|
|
|
+
|
|
|
+#include "modulecomm.h"
|
|
|
+
|
|
|
+using namespace boost::python;
|
|
|
+
|
|
|
+
|
|
|
+namespace py = boost::python;
|
|
|
+namespace np = boost::python::numpy;
|
|
|
+
|
|
|
+// 回调函数类型
|
|
|
+
|
|
|
+
|
|
|
+boost::signals2::signal<void(int)> mySignal;
|
|
|
+py::object mpfunc;
|
|
|
+
|
|
|
+void onSignal(int value) {
|
|
|
+
|
|
|
+ std::cout << "Member function slot called with value: " << value << std::endl;
|
|
|
+ // mpfunc(39);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 假设我们有一个简单的C++函数,它返回一个整数
|
|
|
+class ModuleCommPython
|
|
|
+{
|
|
|
+private:
|
|
|
+ std::thread * mpthread;
|
|
|
+ std::string mstrmemname;
|
|
|
+ void * mpa = nullptr;
|
|
|
+
|
|
|
+ std::shared_ptr<char> mpdata_ptr;
|
|
|
+ int mnRecvdatasize = 0;
|
|
|
+ bool mbUpdate = false;
|
|
|
+ int64_t mnRecvTime = 0;
|
|
|
+ bool mbRun = true;
|
|
|
+
|
|
|
+ std::mutex * mpmutex;
|
|
|
+
|
|
|
+public:
|
|
|
+ ModuleCommPython(){
|
|
|
+ mpa = nullptr;
|
|
|
+ // mpthread = new std::thread(&ModuleCommPython::threadcallback,this);
|
|
|
+ mpmutex = new std::mutex();
|
|
|
+ std::cout<<"create trhead."<<std::endl;
|
|
|
+ }
|
|
|
+ ~ModuleCommPython(){
|
|
|
+ std::cout<<" delete ModuleCommPython"<<std::endl;
|
|
|
+ if(mpa != nullptr)
|
|
|
+ {
|
|
|
+ std::cout<<" delete mpa"<<std::endl;
|
|
|
+ iv::modulecomm::Unregister(mpa);
|
|
|
+ }
|
|
|
+ mbRun = false;
|
|
|
+ // mpthread->join();
|
|
|
+ std::cout<<" complete ModuleCommPython"<<std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ void Release()
|
|
|
+ {
|
|
|
+ std::cout<<" delete ModuleCommPython"<<std::endl;
|
|
|
+ if(mpa != nullptr)
|
|
|
+ {
|
|
|
+ std::cout<<" delete mpa"<<std::endl;
|
|
|
+ iv::modulecomm::Unregister(mpa);
|
|
|
+ }
|
|
|
+ mbRun = false;
|
|
|
+ // mpthread->join();
|
|
|
+ std::cout<<" complete ModuleCommPython"<<std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void TestCall()
|
|
|
+ {
|
|
|
+ static int x =0;
|
|
|
+ x++;
|
|
|
+ mpfunc(x);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetCall(py::object xfun)
|
|
|
+ {
|
|
|
+
|
|
|
+ mpfunc = xfun;
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetMemName(const std::string& strmemname)
|
|
|
+ {
|
|
|
+ mstrmemname = strmemname;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void RegisterSend(const std::string& strmemname,int ndatasize,int npacsize)
|
|
|
+ {
|
|
|
+ std::cout<<"register send."<<std::endl;
|
|
|
+ mpa = iv::modulecomm::RegisterSend(strmemname.data(),ndatasize,npacsize);
|
|
|
+ }
|
|
|
+
|
|
|
+ void RegisterRecv(const std::string& strmemname)
|
|
|
+ {
|
|
|
+ std::cout<<"register recv."<<std::endl;
|
|
|
+ ModuleFun funRecv =std::bind(&ModuleCommPython::UpdateRecv,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
|
|
|
+ mpa = iv::modulecomm::RegisterRecvPlus(strmemname.data(),funRecv);
|
|
|
+ }
|
|
|
+
|
|
|
+ int SendData(np::ndarray& arr,int ndatasize)
|
|
|
+ {
|
|
|
+ std::cout<<"data size is: "<<ndatasize<<std::endl;
|
|
|
+ void* data = arr.get_data();
|
|
|
+ char* data_ptr = static_cast<char*>(data);
|
|
|
+ iv::modulecomm::ModuleSendMsg(mpa,data_ptr,ndatasize);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ int RecvData(np::ndarray& arr,int ndatasize, np::ndarray& nRealSize,np::ndarray& ndRecvTime)
|
|
|
+ {
|
|
|
+ int nRtn = 0;
|
|
|
+ if(mbUpdate == false)
|
|
|
+ {
|
|
|
+ return nRtn; //no data recv
|
|
|
+ }
|
|
|
+
|
|
|
+ mpmutex->lock();
|
|
|
+ if(ndatasize < mnRecvdatasize)
|
|
|
+ {
|
|
|
+ void* data = nRealSize.get_data();
|
|
|
+ int* data_ptr = static_cast<int*>(data);
|
|
|
+ data_ptr[0] = mnRecvdatasize;
|
|
|
+ nRtn = -1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ void* data = arr.get_data();
|
|
|
+ char* data_ptr = static_cast<char*>(data);
|
|
|
+ memcpy(data_ptr,mpdata_ptr.get(),mnRecvdatasize);
|
|
|
+
|
|
|
+ int64_t nRecvTime = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
+
|
|
|
+ void* datatime = ndRecvTime.get_data();
|
|
|
+ int64_t* datatime_ptr = static_cast<int64_t*>(datatime);
|
|
|
+ ndRecvTime[0] = nRecvTime;
|
|
|
+
|
|
|
+ nRtn = mnRecvdatasize;
|
|
|
+ mbUpdate = false;
|
|
|
+ }
|
|
|
+ mpmutex->unlock();
|
|
|
+
|
|
|
+ return nRtn;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void UpdateRecv(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
|
|
|
+ {
|
|
|
+ (void)index;
|
|
|
+ (void)dt;
|
|
|
+ (void)strmemname;
|
|
|
+ // std::cout<<"recv data."<<std::endl;
|
|
|
+ if(nSize == 0)return;
|
|
|
+ mpmutex->lock();
|
|
|
+ mpdata_ptr = std::shared_ptr<char>(new char[nSize]);
|
|
|
+ memcpy(mpdata_ptr.get(),strdata,nSize);
|
|
|
+ mnRecvdatasize = nSize;
|
|
|
+ mbUpdate = true;
|
|
|
+ mpmutex->unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ int Add(np::ndarray& arr) {
|
|
|
+ int nsize = 0;
|
|
|
+ std::cout<<"enter add."<<std::endl;
|
|
|
+ // std::cout << "Shape: "<< py::extract<std::string>(arr.attr("shape")) << std::endl;
|
|
|
+ // std::cout << "Data type: "<< py::extract<std::string>(arr.attr("dtype")) << std::endl;
|
|
|
+
|
|
|
+ // 获取数组的维度
|
|
|
+ const np::dtype& dtype = arr.get_dtype();
|
|
|
+ const Py_intptr_t* shape = arr.get_shape();
|
|
|
+ int ndims = arr.get_nd();
|
|
|
+
|
|
|
+ nsize = ndims;
|
|
|
+
|
|
|
+ // 获取指向数据的指针
|
|
|
+ void* data = arr.get_data();
|
|
|
+
|
|
|
+ std::cout<<" size: "<<nsize<<std::endl;
|
|
|
+
|
|
|
+ // 根据数据类型处理数据
|
|
|
+ if (dtype == np::dtype::get_builtin<unsigned char>()) {
|
|
|
+ unsigned char * data_ptr = static_cast<unsigned char*>(data);
|
|
|
+ for (Py_intptr_t i = 0; i < 5; ++i) {
|
|
|
+ std::cout << (int)(data_ptr[i]) << " "<<std::endl;
|
|
|
+ }
|
|
|
+ data_ptr[2] = 100;
|
|
|
+ std::cout << std::endl;
|
|
|
+ } else {
|
|
|
+ std::cerr << "Unsupported data type" << std::endl;
|
|
|
+ }
|
|
|
+ return nsize;
|
|
|
+ }
|
|
|
+
|
|
|
+ void threadcallback()
|
|
|
+ {
|
|
|
+ mySignal.connect(boost::bind(onSignal, _1));
|
|
|
+ while(mbRun)
|
|
|
+ {
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
+ std::cout<<"thread run "<<std::endl;
|
|
|
+ mySignal(1);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string teststring(const std::string & str)
|
|
|
+ {
|
|
|
+ return str + "hello, change this string.";
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 包装函数,将C++整数转换为boost::python::object并返回
|
|
|
+boost::python::object get_ca_object() {
|
|
|
+ ModuleCommPython * pca = new ModuleCommPython();
|
|
|
+ return py::object(*pca);
|
|
|
+}
|
|
|
+
|
|
|
+// 注册模块和函数
|
|
|
+BOOST_PYTHON_MODULE(modulecommpython) {
|
|
|
+ using namespace boost::python;
|
|
|
+ np::initialize();
|
|
|
+ class_<ModuleCommPython>("ModuleCommPython")
|
|
|
+ .def("Add", &ModuleCommPython::Add)
|
|
|
+ .def("SetCall",&ModuleCommPython::SetCall)
|
|
|
+ .def("TestCall",&ModuleCommPython::TestCall)
|
|
|
+ .def("SendData",&ModuleCommPython::SendData)
|
|
|
+ .def("RecvData",&ModuleCommPython::RecvData)
|
|
|
+ .def("RegisterSend",&ModuleCommPython::RegisterSend)
|
|
|
+ .def("RegisterRecv",&ModuleCommPython::RegisterRecv)
|
|
|
+ .def("teststring",&ModuleCommPython::teststring)
|
|
|
+ ;
|
|
|
+ def("get_ca_object", &get_ca_object);
|
|
|
+}
|
|
|
+
|