预览模式: 普通 | 列表

用boost::asio访问serial port

asio的一个很方便的地方就在于,将socket通讯与serial port通讯等都统一包装了,简化了界面。大体上,使用serial port也和使用socket通讯没啥大区别,但是asio里并没有相信的文档说明有何出入,以下是几个主要地方:

1 使用 boost::asio::serial_port 替换boost::asio::ip::tcp(或udp)::socket, 构造函数自然也得额外追加一个指明是哪一个COM口的字符串。

2 使用boost::asio::serial_port::set_option 函数来设置COM口通讯参数,譬如最常见的设置波特率设置:
                rs232_.set_option( boost::asio::serial_pot_base::baud_rate( 115200);

    所有可设置的串口参数如下: 

asio支持的串口参数:
  1. * boost::asio::serial_port_base::baud_rate   
  2. * boost::asio::serial_port_base::flow_control   
  3. * boost::asio::serial_port_base::parity   
  4. * boost::asio::serial_port_base::stop_bits   
  5. * boost::asio::serial_port_base::character_size  

查看更多...

Tags: boost asio

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 15

Win32字符集转换

 灵感来源于ATL,在工程里要用到字符集转换的时候,又不想扯到ATL(而且ATL并没有用于utf8之类转换的宏),于是自己实现了一个类似的版本。使用起来和ATL很相似。

代码同时含有2个版本,一个是使用_alloca在栈上分配内存,另外一个std::string/std::wstring来做容器。

由于_alloca在栈上分配内存,如果字符串特别长,还是推荐使用stl的版本。另外,如果要在循环里使用这个函数,也请不要选择_alloca版本,否则随时可能因为栈溢出而崩溃。但是请放心,是不会出现因为栈溢出而能被攻击利用的漏洞的:) 

C++代码 LinCharSet.h
  1. #ifndef LIN_CHAR_SET   
  2. #define LIN_CHAR_SET   
  3.   
  4. #include <malloc.h>   
  5.   
  6. #define USE_LIN_CHAR_SET_VARIANT char* _lin_dst = 0; wchar_t* _lin_wdst = 0; int _lin_dst_size = 0;   
  7.   
  8. #define LIN_CHAR_SET_NO_WARNING  _lin_dst; _lin_wdst;_lin_dst_size;   
  9.   
  10. #define USE_LIN_CHAR_SET USE_LIN_CHAR_SET_VARIANT;LIN_CHAR_SET_NO_WARNING   
  11.   
  12.   
  13. #ifdef LIN_CHAR_SET_USE_STL   
  14.   
  15. #include <string>   
  16. std::string _w2a( const std::wstring& pwcsSrc, int codepage)   
  17. {   
  18.     USE_LIN_CHAR_SET_VARIANT;   
  19.     _lin_dst_size = pwcsSrc.size()*3;   
  20.     _lin_dst = new char [ _lin_dst_size];   
  21.     if( _lin_dst == 0) return std::string();   
  22.   
  23.     _lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc.c_str(), pwcsSrc.length(), _lin_dst, _lin_dst_size, 0, 0);   
  24.   
  25.     if( _lin_dst_size == 0) return std::string();   
  26.   
  27.     _lin_dst[_lin_dst_size] = 0;   
  28.     std::string result = _lin_dst;   
  29.     delete[] _lin_dst;   
  30.     return result;   
  31. }   
  32.   
  33. std::wstring _a2w( const std::string& pszSrc, int codepage)   
  34. {   
  35.     USE_LIN_CHAR_SET_VARIANT;   
  36.     _lin_dst_size = pszSrc.size()*2;   
  37.     _lin_wdst = new wchar_t [ _lin_dst_size];   
  38.     if( _lin_wdst == 0) return std::wstring();   
  39.   
  40.     _lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc.c_str(), pszSrc.length(), _lin_wdst,_lin_dst_size);   
  41.   
  42.     if( _lin_dst_size == 0) return std::wstring();   
  43.   
  44.     _lin_wdst[_lin_dst_size] = 0;   
  45.     std::wstring result = _lin_wdst;   
  46.     delete[] _lin_wdst;   
  47.     return result;}   
  48.   
  49. #else   
  50. #define _w2a( pwcsSrc, codepage) ( pwcsSrc == 0? 0:( \   
  51.     (_lin_dst = (char*)_alloca( ((_lin_dst_size = (int)wcslen( pwcsSrc))+ 1)*3))== 0? 0 : (\   
  52.     (_lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc, _lin_dst_size, _lin_dst, _lin_dst_size*3, 0, 0))==0? \   
  53.     ((_lin_dst[0]=0)==0 ? _lin_dst:0): (\   
  54.     (_lin_dst[_lin_dst_size] = 0) == 0? _lin_dst : 0))))   
  55.   
  56. #define _a2w( pszSrc, codepage) (pszSrc == 0? 0 : (\   
  57.     (_lin_wdst = (wchar_t*)_alloca( ((_lin_dst_size = (int)strlen( pszSrc)) + 1)*2)) == 0? 0 : (\   
  58.     (_lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc, _lin_dst_size, _lin_wdst,_lin_dst_size + sizeof(wchar_t))) == 0? \   
  59.     ((_lin_wdst[0]=0)==0? _lin_wdst:0) : (\   
  60.     (_lin_wdst[ _lin_dst_size] = 0) == 0? _lin_wdst: 0))))   
  61.   
  62. #endif   
  63.   
  64.   
  65. #define _utf82w( pszSrc) _a2w( pszSrc, CP_UTF8)   
  66. #define _w2utf8( pszSrc) _w2a( pszSrc, CP_UTF8)   
  67.   
  68. #define _utf72w( pszSrc) _a2w( pszSrc, CP_UTF7)   
  69. #define _w2utf7( pszSrc) _w2a( pszSrc, CP_UTF7)   
  70.   
  71.   
  72. // 导出的宏   
  73. #define a2w(pszSrc) _a2w(pszSrc, CP_ACP)   
  74. #define w2a(tcsSrc) _w2a(tcsSrc, CP_ACP)   
  75.   
  76. #ifdef UNICODE   
  77. #define a2t(pszSrc) a2w(pszSrc)   
  78. #define t2a(tcsSrc) w2a(tcsSrc)   
  79. #define w2t(wcsSrc) wcsSrc;   
  80. #define t2w(tcsSrc) tcsSrc;   
  81. #else   
  82. #define a2t(pszSrc) pszSrc   
  83. #define t2a(tcsSrc) tcsSrc   
  84. #define w2t(wcsSrc) wta(wcsSrc)   
  85. #define t2w(tcsSrc) a2w(tcsSrc)   
  86. #endif   
  87.   
  88. #define w2utf8(wcsSrc) _w2utf8(wcsSrc)   
  89. #define utf82w(pszSrc) _utf82w(pszSrc)   
  90. #define w2utf7(wcsSrc) _w2utf7(wcsSrc)   
  91. #define utf72w(pszSrc) _utf72w(pszSrc)   
  92.   
  93. #define a2utf8(pszSrc) w2utf8(a2w(pszSrc))   
  94. #define a2utf7(pszSrc) w2utf7(a2w(pszSrc))   
  95. #define utf82a(pszSrc) w2a(utf82w(pszSrc))   
  96. #define utf72a(pszSrc) w2a(utf72w(pszSrc))   
  97. #define t2utf8(tcsSrc) w2utf8(tcsSrc)   
  98. #define t2utf7(tcsSrc) w2utf7(tcsSrc)   
  99. #define utf82t(pszSrc) w2t(utf82w(pszSrc))   
  100. #define utf72t(pszSrc) w2t(utf72w(pszSrc))   
  101.   
  102. #endif  

使用起来很简单,就似ATL

C++代码  main.cpp
  1. #include <windows.h>   
  2. #include <TCHAR.h>   
  3. #include "LinCharSet.h"   
  4. #include <assert.h>   
  5. #include <iostream>   
  6.   
  7. void main()   
  8. {   
  9. #ifdef WIN32   
  10.     int __tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );   
  11.   
  12.     __tmpFlag |= _CRTDBG_LEAK_CHECK_DF;   
  13.   
  14.     _CrtSetDbgFlag( __tmpFlag );   
  15. #endif   
  16.     USE_LIN_CHAR_SET;   
  17.   
  18. #ifdef LIN_CHAR_SET_USE_STL   
  19.     std::wstring pwszSrc = _T("hehe中文hehe");   
  20.     std::string pOut = t2a( pwszSrc);   
  21.     std::wstring pDest = a2t( pOut);   
  22.     std::wstring p1 = t2w( pDest);   
  23.     std::string putf8 = a2utf8( pOut);   
  24.     std::cout << putf8 << std::endl;   
  25.     std::string pw = utf82a( a2utf8(pOut));   
  26.   
  27.     forint i = 0; i<=1000000; i++)   
  28.     {   
  29.         pOut = t2a(pwszSrc);   
  30.     }   
  31.   
  32.     std::cout << pw << std::endl;   
  33. #else   
  34.     TCHAR* pwszSrc = _T("hehe中文hehe");   
  35.     char* pOut = t2a( pwszSrc);   
  36.     TCHAR* pDest = a2t( pOut);   
  37.     wchar_t* p1 = t2w( pDest);   
  38.     char* putf8 = a2utf8( pOut);   
  39.     std::cout << putf8 << std::endl;   
  40.     char* pw = utf82a( a2utf8(pOut));   
  41.   
  42.     std::cout << pw << std::endl;   
  43. #endif   
  44.   
  45.     return ;   
  46. }  

查看更多...

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 50

汇编与cpu, 一次代码优化的体验

    之前提到,CvSub函数在新摄像头下处理数据的效率十分低下。后来自己用C++实现了一个针对性的函数,将cpu占用率缩减了不少。回家后,突然有了一个想法,于是有了以下的讨论。

算法简单描叙就是这样的,有3个unsigned char数组分别位src, ref, dst,从src和ref计算得到dst,结果应当是这样的: 对每一个序号为i的元素,dst[i] = (src[i]-ref[i])  > 0 ? ( src[i]-ref[i]) : 0; 我这里不需要特复杂的计算,另外,src, ref,dst总是与字对齐,而且长度也是4的倍数。

以下是过程:) 

C++代码
  1. // 第1版本 最直观的写法   
  2. void func_a( unsigned char* src, unsigned char* ref, unsigned char* dest, int size)   
  3. {   
  4.     forint i = 0; i < size; i++)   
  5.     {   
  6.         dest[i] = ( src[i] > ref[i]) ? (src[i] - ref[i]) : 0;
  7.     }   
  8. }   

 第一个版本是我在公司完成的缩减版,算法很直接。效率已经比要适用各种情况的CvSub提速很多,但是仍不够理想。

查看更多...

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 54

OpenCV之CvSub

今天工作中遇到一个问题,采用新的摄像头后(使用它的SDK),程序的cpu占用率剧增至70%左右。而之前,即使是采用usb摄像头,也才30%的cpu占用率,用采集卡的时候,更是只有5%。新的摄像头尽管fps高了一倍,但是采用的1394接口,理论上不应该这么慢。

检查了很久,发现不是采集部分的问题,因为我写的单纯采集的程序,cpu占用率一般为0,至多不超过2%。

后来慢慢的排查问题,终于找到罪魁祸首:当调用CvSub后,程序的性能急剧下降。

由于时间问题,我没再去对比不同的摄像头采集的数据后,为啥这个摄像头的数据,会导致的cvsub会如此耗资源。

查看更多...

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 34

成员对象的虚拟继承

代码如下,已通过vc6,2005,2008和mingw的测试

C++代码
  1. #include <iostream>   
  2.   
  3. class A{   
  4. public:   
  5.   virtual struct    // 要兼容各种编译器,这里不要直接使用virtual int i   
  6.   {   
  7.       int i;   
  8.   };   
  9. };   
  10.   
  11. class B : virtual public A   
  12. {   
  13. };   
  14.   
  15. class C: virtual  public A   
  16. {   
  17. };   
  18.   
  19. class D: virtual public B, virtual public C   
  20. {   
  21. };   
  22.   
  23. int main()   
  24. {   
  25.     class D* d = new D;   
  26.     class B* b = d;   
  27.     class C* c = d;   
  28.     b->i = 3;   
  29.   
  30.     std::cout << 'B' << sizeof(B) << '\t' << b->i << std::endl;   
  31.     std::cout << 'D' << sizeof(D) << '\t' << d->i << std::endl;   
  32.   
  33.     c->i = 5;   
  34.   
  35.     std::cout << 'B' << sizeof(B) << '\t' << b->i << std::endl;   
  36.     std::cout << 'D' << sizeof(D) << '\t' << d->i << std::endl;   
  37.     return 0;   
  38. }  

 

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 139

dll静态编译的问题

当选择multi-threaded或者multi-threaded debug静态编译时,请注意,编译器会为该dll单独实现一个c++ 运行库环境。这时,exe文件或者其他dll文件也使用静态编译等的时候,编译器又会实现多个c++运行库环境。在这个时侯,(由于微软的stl实现基于引用计数,)多个运行库的存在,就可能导致引用计数的错误(因为各个运行库分别计数)。

直接导致的问题就是,如果dll导出函数输入或者输出数据类型中使用了stl类时,程序有可能因为引用计数的问题而过早析构该对象,而导致后续访问野指针,应用程序崩溃。

所以当你选择静态编译的时候,记住返回的函数或者输入的参数,都不要使用stl类对象,否则程序将不稳定。

C++代码
  1. // 以std::string为示例,如下风格的函数不可用   
  2. std::string getString(); // 返回一个std::string或者std::string&   
  3.   
  4. void getString( std::string&);  //输入参数是std::string&等   
  5.   
  6. void setString( const std::string&); //同样会导致不可预料的错误,虽然输入的值是const类型的!  

 其他stl类库也都一样,不能作为输入或者输出的数据类型。

查看更多...

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 277

拷贝构造与gcc

    写的程序怎么也没法在gcc下完成编译,vs2005和2008下编译很正常。研究了好一阵子,最后发现是拷贝构造的问题。

C++代码
  1. CIterator( CIterator &);  // 如果是这样,使用此构造的时候提示找不到实现          
  2.   
  3. // 改写成const参数   
  4. CIterator( const CIterator&); // OK,代码编译完全正常!即使我提供的参数是非const类型的   

有一点晕。

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 186

#define与多条语句

 折腾了一阵子。写法就是利用3元运算符  a == b ? c : d来让其成为一条语句。宏看上去有点累,但是有些情况下,确实非常有效的。譬如下面的代码,如果用inline,由于编译器的支持问题,并不一定会真的编译成inline,那么_alloca返回的数据就可能失效而导致崩溃了。但是宏不会:)

C++代码
  1. #define _w2a( pwcsSrc, codepage) ( pwcsSrc == 0? 0:( \   
  2.     (_lin_dst = (char*)_alloca( ((_lin_dst_size = (int)wcslen( pwcsSrc))+ 1)*3))== 0? 0 : (\   
  3.     (_lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc, _lin_dst_size, _lin_dst, _lin_dst_size*3, 0, 0))==0? \   
  4.     ((_lin_dst[0]=0)==0 ? _lin_dst:0): (\   
  5.     (_lin_dst[_lin_dst_size] = 0) == 0? _lin_dst : 0))))   
  6.   
  7.   
  8. #define _a2w( pszSrc, codepage) (pszSrc == 0? 0 : (\   
  9.     (_lin_wdst = (wchar_t*)_alloca( ((_lin_dst_size = (int)strlen( pszSrc)) + 1)*2)) == 0? 0 : (\   
  10.     (_lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc, _lin_dst_size, _lin_wdst,_lin_dst_size + sizeof(wchar_t))) == 0? \   
  11.     ((_lin_wdst[0]=0)==0? _lin_wdst:0) : (\   
  12.     (_lin_wdst[ _lin_dst_size] = 0) == 0? _lin_wdst: 0))))  

 

Tags: define

分类:C/C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 427