用boost::asio访问serial port
作者:ClassyK 日期:2009-01-02
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);
所有可设置的串口参数如下:
- * boost::asio::serial_port_base::baud_rate
- * boost::asio::serial_port_base::flow_control
- * boost::asio::serial_port_base::parity
- * boost::asio::serial_port_base::stop_bits
- * boost::asio::serial_port_base::character_size
Win32字符集转换
作者:ClassyK 日期:2008-12-29
灵感来源于ATL,在工程里要用到字符集转换的时候,又不想扯到ATL(而且ATL并没有用于utf8之类转换的宏),于是自己实现了一个类似的版本。使用起来和ATL很相似。
代码同时含有2个版本,一个是使用_alloca在栈上分配内存,另外一个std::string/std::wstring来做容器。
由于_alloca在栈上分配内存,如果字符串特别长,还是推荐使用stl的版本。另外,如果要在循环里使用这个函数,也请不要选择_alloca版本,否则随时可能因为栈溢出而崩溃。但是请放心,是不会出现因为栈溢出而能被攻击利用的漏洞的:)
- #ifndef LIN_CHAR_SET
- #define LIN_CHAR_SET
- #include <malloc.h>
- #define USE_LIN_CHAR_SET_VARIANT char* _lin_dst = 0; wchar_t* _lin_wdst = 0; int _lin_dst_size = 0;
- #define LIN_CHAR_SET_NO_WARNING _lin_dst; _lin_wdst;_lin_dst_size;
- #define USE_LIN_CHAR_SET USE_LIN_CHAR_SET_VARIANT;LIN_CHAR_SET_NO_WARNING
- #ifdef LIN_CHAR_SET_USE_STL
- #include <string>
- std::string _w2a( const std::wstring& pwcsSrc, int codepage)
- {
- USE_LIN_CHAR_SET_VARIANT;
- _lin_dst_size = pwcsSrc.size()*3;
- _lin_dst = new char [ _lin_dst_size];
- if( _lin_dst == 0) return std::string();
- _lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc.c_str(), pwcsSrc.length(), _lin_dst, _lin_dst_size, 0, 0);
- if( _lin_dst_size == 0) return std::string();
- _lin_dst[_lin_dst_size] = 0;
- std::string result = _lin_dst;
- delete[] _lin_dst;
- return result;
- }
- std::wstring _a2w( const std::string& pszSrc, int codepage)
- {
- USE_LIN_CHAR_SET_VARIANT;
- _lin_dst_size = pszSrc.size()*2;
- _lin_wdst = new wchar_t [ _lin_dst_size];
- if( _lin_wdst == 0) return std::wstring();
- _lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc.c_str(), pszSrc.length(), _lin_wdst,_lin_dst_size);
- if( _lin_dst_size == 0) return std::wstring();
- _lin_wdst[_lin_dst_size] = 0;
- std::wstring result = _lin_wdst;
- delete[] _lin_wdst;
- return result;}
- #else
- #define _w2a( pwcsSrc, codepage) ( pwcsSrc == 0? 0:( \
- (_lin_dst = (char*)_alloca( ((_lin_dst_size = (int)wcslen( pwcsSrc))+ 1)*3))== 0? 0 : (\
- (_lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc, _lin_dst_size, _lin_dst, _lin_dst_size*3, 0, 0))==0? \
- ((_lin_dst[0]=0)==0 ? _lin_dst:0): (\
- (_lin_dst[_lin_dst_size] = 0) == 0? _lin_dst : 0))))
- #define _a2w( pszSrc, codepage) (pszSrc == 0? 0 : (\
- (_lin_wdst = (wchar_t*)_alloca( ((_lin_dst_size = (int)strlen( pszSrc)) + 1)*2)) == 0? 0 : (\
- (_lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc, _lin_dst_size, _lin_wdst,_lin_dst_size + sizeof(wchar_t))) == 0? \
- ((_lin_wdst[0]=0)==0? _lin_wdst:0) : (\
- (_lin_wdst[ _lin_dst_size] = 0) == 0? _lin_wdst: 0))))
- #endif
- #define _utf82w( pszSrc) _a2w( pszSrc, CP_UTF8)
- #define _w2utf8( pszSrc) _w2a( pszSrc, CP_UTF8)
- #define _utf72w( pszSrc) _a2w( pszSrc, CP_UTF7)
- #define _w2utf7( pszSrc) _w2a( pszSrc, CP_UTF7)
- // 导出的宏
- #define a2w(pszSrc) _a2w(pszSrc, CP_ACP)
- #define w2a(tcsSrc) _w2a(tcsSrc, CP_ACP)
- #ifdef UNICODE
- #define a2t(pszSrc) a2w(pszSrc)
- #define t2a(tcsSrc) w2a(tcsSrc)
- #define w2t(wcsSrc) wcsSrc;
- #define t2w(tcsSrc) tcsSrc;
- #else
- #define a2t(pszSrc) pszSrc
- #define t2a(tcsSrc) tcsSrc
- #define w2t(wcsSrc) wta(wcsSrc)
- #define t2w(tcsSrc) a2w(tcsSrc)
- #endif
- #define w2utf8(wcsSrc) _w2utf8(wcsSrc)
- #define utf82w(pszSrc) _utf82w(pszSrc)
- #define w2utf7(wcsSrc) _w2utf7(wcsSrc)
- #define utf72w(pszSrc) _utf72w(pszSrc)
- #define a2utf8(pszSrc) w2utf8(a2w(pszSrc))
- #define a2utf7(pszSrc) w2utf7(a2w(pszSrc))
- #define utf82a(pszSrc) w2a(utf82w(pszSrc))
- #define utf72a(pszSrc) w2a(utf72w(pszSrc))
- #define t2utf8(tcsSrc) w2utf8(tcsSrc)
- #define t2utf7(tcsSrc) w2utf7(tcsSrc)
- #define utf82t(pszSrc) w2t(utf82w(pszSrc))
- #define utf72t(pszSrc) w2t(utf72w(pszSrc))
- #endif
使用起来很简单,就似ATL
- #include <windows.h>
- #include <TCHAR.h>
- #include "LinCharSet.h"
- #include <assert.h>
- #include <iostream>
- void main()
- {
- #ifdef WIN32
- int __tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
- __tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
- _CrtSetDbgFlag( __tmpFlag );
- #endif
- USE_LIN_CHAR_SET;
- #ifdef LIN_CHAR_SET_USE_STL
- std::wstring pwszSrc = _T("hehe中文hehe");
- std::string pOut = t2a( pwszSrc);
- std::wstring pDest = a2t( pOut);
- std::wstring p1 = t2w( pDest);
- std::string putf8 = a2utf8( pOut);
- std::cout << putf8 << std::endl;
- std::string pw = utf82a( a2utf8(pOut));
- for( int i = 0; i<=1000000; i++)
- {
- pOut = t2a(pwszSrc);
- }
- std::cout << pw << std::endl;
- #else
- TCHAR* pwszSrc = _T("hehe中文hehe");
- char* pOut = t2a( pwszSrc);
- TCHAR* pDest = a2t( pOut);
- wchar_t* p1 = t2w( pDest);
- char* putf8 = a2utf8( pOut);
- std::cout << putf8 << std::endl;
- char* pw = utf82a( a2utf8(pOut));
- std::cout << pw << std::endl;
- #endif
- return ;
- }
汇编与cpu, 一次代码优化的体验
作者:ClassyK 日期:2008-12-29
之前提到,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的倍数。
以下是过程:)
- // 第1版本 最直观的写法
- void func_a( unsigned char* src, unsigned char* ref, unsigned char* dest, int size)
- {
- for( int i = 0; i < size; i++)
- {
- dest[i] = ( src[i] > ref[i]) ? (src[i] - ref[i]) : 0;
- }
- }
第一个版本是我在公司完成的缩减版,算法很直接。效率已经比要适用各种情况的CvSub提速很多,但是仍不够理想。
OpenCV之CvSub
作者:ClassyK 日期:2008-12-26
今天工作中遇到一个问题,采用新的摄像头后(使用它的SDK),程序的cpu占用率剧增至70%左右。而之前,即使是采用usb摄像头,也才30%的cpu占用率,用采集卡的时候,更是只有5%。新的摄像头尽管fps高了一倍,但是采用的1394接口,理论上不应该这么慢。
检查了很久,发现不是采集部分的问题,因为我写的单纯采集的程序,cpu占用率一般为0,至多不超过2%。
后来慢慢的排查问题,终于找到罪魁祸首:当调用CvSub后,程序的性能急剧下降。
由于时间问题,我没再去对比不同的摄像头采集的数据后,为啥这个摄像头的数据,会导致的cvsub会如此耗资源。
成员对象的虚拟继承
作者:ClassyK 日期:2008-11-16
代码如下,已通过vc6,2005,2008和mingw的测试
- #include <iostream>
- class A{
- public:
- virtual struct // 要兼容各种编译器,这里不要直接使用virtual int i
- {
- int i;
- };
- };
- class B : virtual public A
- {
- };
- class C: virtual public A
- {
- };
- class D: virtual public B, virtual public C
- {
- };
- int main()
- {
- class D* d = new D;
- class B* b = d;
- class C* c = d;
- b->i = 3;
- std::cout << 'B' << sizeof(B) << '\t' << b->i << std::endl;
- std::cout << 'D' << sizeof(D) << '\t' << d->i << std::endl;
- c->i = 5;
- std::cout << 'B' << sizeof(B) << '\t' << b->i << std::endl;
- std::cout << 'D' << sizeof(D) << '\t' << d->i << std::endl;
- return 0;
- }
dll静态编译的问题
作者:ClassyK 日期:2008-10-21
当选择multi-threaded或者multi-threaded debug静态编译时,请注意,编译器会为该dll单独实现一个c++ 运行库环境。这时,exe文件或者其他dll文件也使用静态编译等的时候,编译器又会实现多个c++运行库环境。在这个时侯,(由于微软的stl实现基于引用计数,)多个运行库的存在,就可能导致引用计数的错误(因为各个运行库分别计数)。
直接导致的问题就是,如果dll导出函数输入或者输出数据类型中使用了stl类时,程序有可能因为引用计数的问题而过早析构该对象,而导致后续访问野指针,应用程序崩溃。
所以当你选择静态编译的时候,记住返回的函数或者输入的参数,都不要使用stl类对象,否则程序将不稳定。
- // 以std::string为示例,如下风格的函数不可用
- std::string getString(); // 返回一个std::string或者std::string&
- void getString( std::string&); //输入参数是std::string&等
- void setString( const std::string&); //同样会导致不可预料的错误,虽然输入的值是const类型的!
其他stl类库也都一样,不能作为输入或者输出的数据类型。
拷贝构造与gcc
作者:ClassyK 日期:2008-09-28
#define与多条语句
作者:ClassyK 日期:2008-08-08
折腾了一阵子。写法就是利用3元运算符 a == b ? c : d来让其成为一条语句。宏看上去有点累,但是有些情况下,确实非常有效的。譬如下面的代码,如果用inline,由于编译器的支持问题,并不一定会真的编译成inline,那么_alloca返回的数据就可能失效而导致崩溃了。但是宏不会:)
- #define _w2a( pwcsSrc, codepage) ( pwcsSrc == 0? 0:( \
- (_lin_dst = (char*)_alloca( ((_lin_dst_size = (int)wcslen( pwcsSrc))+ 1)*3))== 0? 0 : (\
- (_lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc, _lin_dst_size, _lin_dst, _lin_dst_size*3, 0, 0))==0? \
- ((_lin_dst[0]=0)==0 ? _lin_dst:0): (\
- (_lin_dst[_lin_dst_size] = 0) == 0? _lin_dst : 0))))
- #define _a2w( pszSrc, codepage) (pszSrc == 0? 0 : (\
- (_lin_wdst = (wchar_t*)_alloca( ((_lin_dst_size = (int)strlen( pszSrc)) + 1)*2)) == 0? 0 : (\
- (_lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc, _lin_dst_size, _lin_wdst,_lin_dst_size + sizeof(wchar_t))) == 0? \
- ((_lin_wdst[0]=0)==0? _lin_wdst:0) : (\
- (_lin_wdst[ _lin_dst_size] = 0) == 0? _lin_wdst: 0))))
Tags: define

