modulecommpython.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include <boost/python.hpp>
  2. #include <boost/python/numpy.hpp>
  3. #include <boost/thread.hpp>
  4. #include <boost/signals2.hpp>
  5. #include <iostream>
  6. #include <thread>
  7. #include <chrono>
  8. #include <Python.h>
  9. #include <string>
  10. #include <mutex>
  11. #include "modulecomm.h"
  12. using namespace boost::python;
  13. namespace py = boost::python;
  14. namespace np = boost::python::numpy;
  15. // 回调函数类型
  16. boost::signals2::signal<void(int)> mySignal;
  17. py::object mpfunc;
  18. void onSignal(int value) {
  19. std::cout << "Member function slot called with value: " << value << std::endl;
  20. // mpfunc(39);
  21. }
  22. // 假设我们有一个简单的C++函数,它返回一个整数
  23. class ModuleCommPython
  24. {
  25. private:
  26. std::thread * mpthread;
  27. std::string mstrmemname;
  28. void * mpa = nullptr;
  29. std::shared_ptr<char> mpdata_ptr;
  30. int mnRecvdatasize = 0;
  31. bool mbUpdate = false;
  32. int64_t mnRecvTime = 0;
  33. bool mbRun = true;
  34. std::mutex * mpmutex;
  35. public:
  36. ModuleCommPython(){
  37. mpa = nullptr;
  38. // mpthread = new std::thread(&ModuleCommPython::threadcallback,this);
  39. mpmutex = new std::mutex();
  40. std::cout<<"create trhead."<<std::endl;
  41. }
  42. ~ModuleCommPython(){
  43. std::cout<<" delete ModuleCommPython"<<std::endl;
  44. if(mpa != nullptr)
  45. {
  46. std::cout<<" delete mpa"<<std::endl;
  47. iv::modulecomm::Unregister(mpa);
  48. }
  49. mbRun = false;
  50. // mpthread->join();
  51. std::cout<<" complete ModuleCommPython"<<std::endl;
  52. }
  53. void Release()
  54. {
  55. std::cout<<" delete ModuleCommPython"<<std::endl;
  56. if(mpa != nullptr)
  57. {
  58. std::cout<<" delete mpa"<<std::endl;
  59. iv::modulecomm::Unregister(mpa);
  60. }
  61. mbRun = false;
  62. // mpthread->join();
  63. std::cout<<" complete ModuleCommPython"<<std::endl;
  64. }
  65. void TestCall()
  66. {
  67. static int x =0;
  68. x++;
  69. mpfunc(x);
  70. }
  71. void SetCall(py::object xfun)
  72. {
  73. mpfunc = xfun;
  74. }
  75. void SetMemName(const std::string& strmemname)
  76. {
  77. mstrmemname = strmemname;
  78. }
  79. void RegisterSend(const std::string& strmemname,int ndatasize,int npacsize)
  80. {
  81. std::cout<<"register send."<<std::endl;
  82. mpa = iv::modulecomm::RegisterSend(strmemname.data(),ndatasize,npacsize);
  83. }
  84. void RegisterRecv(const std::string& strmemname)
  85. {
  86. std::cout<<"register recv."<<std::endl;
  87. ModuleFun funRecv =std::bind(&ModuleCommPython::UpdateRecv,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
  88. mpa = iv::modulecomm::RegisterRecvPlus(strmemname.data(),funRecv);
  89. }
  90. int SendData(np::ndarray& arr,int ndatasize)
  91. {
  92. std::cout<<"data size is: "<<ndatasize<<std::endl;
  93. void* data = arr.get_data();
  94. char* data_ptr = static_cast<char*>(data);
  95. iv::modulecomm::ModuleSendMsg(mpa,data_ptr,ndatasize);
  96. return 0;
  97. }
  98. int RecvData(np::ndarray& arr,int ndatasize, np::ndarray& nRealSize,np::ndarray& ndRecvTime)
  99. {
  100. int nRtn = 0;
  101. if(mbUpdate == false)
  102. {
  103. return nRtn; //no data recv
  104. }
  105. mpmutex->lock();
  106. if(ndatasize < mnRecvdatasize)
  107. {
  108. void* data = nRealSize.get_data();
  109. int* data_ptr = static_cast<int*>(data);
  110. data_ptr[0] = mnRecvdatasize;
  111. nRtn = -1;
  112. }
  113. else
  114. {
  115. void* data = arr.get_data();
  116. char* data_ptr = static_cast<char*>(data);
  117. memcpy(data_ptr,mpdata_ptr.get(),mnRecvdatasize);
  118. int64_t nRecvTime = std::chrono::system_clock::now().time_since_epoch().count();
  119. void* datatime = ndRecvTime.get_data();
  120. int64_t* datatime_ptr = static_cast<int64_t*>(datatime);
  121. ndRecvTime[0] = nRecvTime;
  122. nRtn = mnRecvdatasize;
  123. mbUpdate = false;
  124. }
  125. mpmutex->unlock();
  126. return nRtn;
  127. }
  128. void UpdateRecv(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  129. {
  130. (void)index;
  131. (void)dt;
  132. (void)strmemname;
  133. // std::cout<<"recv data."<<std::endl;
  134. if(nSize == 0)return;
  135. mpmutex->lock();
  136. mpdata_ptr = std::shared_ptr<char>(new char[nSize]);
  137. memcpy(mpdata_ptr.get(),strdata,nSize);
  138. mnRecvdatasize = nSize;
  139. mbUpdate = true;
  140. mpmutex->unlock();
  141. }
  142. int Add(np::ndarray& arr) {
  143. int nsize = 0;
  144. std::cout<<"enter add."<<std::endl;
  145. // std::cout << "Shape: "<< py::extract<std::string>(arr.attr("shape")) << std::endl;
  146. // std::cout << "Data type: "<< py::extract<std::string>(arr.attr("dtype")) << std::endl;
  147. // 获取数组的维度
  148. const np::dtype& dtype = arr.get_dtype();
  149. const Py_intptr_t* shape = arr.get_shape();
  150. int ndims = arr.get_nd();
  151. nsize = ndims;
  152. // 获取指向数据的指针
  153. void* data = arr.get_data();
  154. std::cout<<" size: "<<nsize<<std::endl;
  155. // 根据数据类型处理数据
  156. if (dtype == np::dtype::get_builtin<unsigned char>()) {
  157. unsigned char * data_ptr = static_cast<unsigned char*>(data);
  158. for (Py_intptr_t i = 0; i < 5; ++i) {
  159. std::cout << (int)(data_ptr[i]) << " "<<std::endl;
  160. }
  161. data_ptr[2] = 100;
  162. std::cout << std::endl;
  163. } else {
  164. std::cerr << "Unsupported data type" << std::endl;
  165. }
  166. return nsize;
  167. }
  168. void threadcallback()
  169. {
  170. mySignal.connect(boost::bind(onSignal, _1));
  171. while(mbRun)
  172. {
  173. std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  174. std::cout<<"thread run "<<std::endl;
  175. mySignal(1);
  176. }
  177. }
  178. std::string teststring(const std::string & str)
  179. {
  180. return str + "hello, change this string.";
  181. }
  182. };
  183. // 包装函数,将C++整数转换为boost::python::object并返回
  184. boost::python::object get_ca_object() {
  185. ModuleCommPython * pca = new ModuleCommPython();
  186. return py::object(*pca);
  187. }
  188. // 注册模块和函数
  189. BOOST_PYTHON_MODULE(modulecommpython) {
  190. using namespace boost::python;
  191. np::initialize();
  192. class_<ModuleCommPython>("ModuleCommPython")
  193. .def("Add", &ModuleCommPython::Add)
  194. .def("SetCall",&ModuleCommPython::SetCall)
  195. .def("TestCall",&ModuleCommPython::TestCall)
  196. .def("SendData",&ModuleCommPython::SendData)
  197. .def("RecvData",&ModuleCommPython::RecvData)
  198. .def("RegisterSend",&ModuleCommPython::RegisterSend)
  199. .def("RegisterRecv",&ModuleCommPython::RegisterRecv)
  200. .def("teststring",&ModuleCommPython::teststring)
  201. ;
  202. def("get_ca_object", &get_ca_object);
  203. }