(转)C/C++源文件编码方式

好文一篇,转来共赏^_^

"汉字"
GBK编码:BA BA , D7 D6
UTF-8编码:E6 B1 89, E5 AD 97
UTF-16BE编码:6C 49, 5B 57

2356注:文中的GCC指GCC中的C/C++编译器,CL指Visual C++编译器

两种常用编译器gcc,cl中对Unicode字面值的实现:

GCC
gcc中跟编码方式转换有关的三个编译选项:

-finput-charset=charset,此选项指定源文件本身的编码方式,默认为UTF-8(有无BOM均可)。例如当我们的源代码文件保存为GBK时,则也应当将此选项的值指定为GBK。
-fwide-exec-charset=charset,此选项指定宽字符或宽字符串的字面值常量的内部编码方式,默认为UTF-32或UTF-16,对应wchar_t的宽度。wchar_t的宽度依赖平台实现,windows 实现为2字节宽,linux 实现为4字节宽。例如指定此选项为GBK,则宽字符或宽字符串常量将会以GBK编码方式存储而不是默认的UTF-32或UTF-16编码方式。
-fexec-charset=charset,此选项指定窄字符或窄字符串的字面值常量的内部编码方式,默认为UTF-8。例如指定此选项为GBK,则窄字符或窄字符串常量将会以GBK编码方式存储而不是默认的UTF-8编码方式。

有了以上铺垫,下面两条语句的意义就很清楚了:
char cstr[] = "汉字"; //将"汉字"由-finput-charset指定的编码方式转换成由-fexec-charset指定的编码方式。
wchar_t wstr[] = L"汉字"; //将"汉字"由-finput-charset指定的编码方式转换成由-fwide-exec-charset指定的编码方式。

注1:gcc在4.4.0版本以前存在bug,不能编译带BOM的UTF-8源文件。参见http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33415

注2:Qt自带的mingw gcc 4.4.0貌似有bug,不能支持-finput-charset选项;TDM gcc 4.5.1则没有这个问题。
注3:即便TDM gcc 也不能支持UTF-16,无论BE或者LE。症状是好像只要包含了头文件--无论是标准库的头文件还是Qt的头文件,就无法编译通过,不包含头文件则是可以编译通过的。

CL
cl 没有提供类似gcc指定编码方式的编译选项,只能使用默认值或靠自动识别:

对应gcc的-finput-charset,cl 能自动识别源文件的编码方式,cl 支持的源文件编码方式有:UTF-16(BE,LE均可,有无BOM均可),UTF-8(带BOM),除此之外的源文件均认为是ANSI编码方式(包括不带BOM的UTF-8)。所以使用VC编译不带BOM的UTF-8文件时要特别注意,vc会将此文件当做ANSI也就是GBK编码格式。否则经常会出这样的警告:该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失。

对应gcc的-fwide-exec-charset, cl 固定使用UTF-16编码方式。
对应gcc的-fexec-charset, cl 固定使用ANSI编码方式。

再看同样的语句在 cl 下的行为:

对于源文件的编码方式为UTF-16BE,UTF-16LE, UTF-8(带BOM):
char cstr[] = "汉字"; //将源文件中的"汉字"从当前编码方式转换成ANSI编码方式,即GBK。
wchar_t wstr[] = L"汉字"; //将源文件中的"汉字"从当前编码方式转换成UTF-16编码方式。

对于其他编码方式的源文件(包括无BOM的UTF-8),实际上会被当做ANSI编码,即GBK:
char cstr[] = "汉字"; //认为已经是ANSI编码了,故没有转换发生,cstr中依旧是"汉字"的原始编码。例如,如果源文件的编码方式为无BOM的UTF-8,则cstr中依旧是"汉字"的UTF-8编码。
wchar_t wstr[] = L"汉字"; //无论源文件采用何种编码方式,都将"汉字"当做ANSI编码,转换成UTF-16编码。这样硬转的结果当然是除了当前是GBK编码时能正常转换,其余各种编码方式得到的只能是乱码一堆。

有关cl对unicode的支持请参考:http://msdn.microsoft.com/en-us/library/xwy0e8f2(v=VS.90).aspx

C++1x

面对如此混乱的局面,c++1x提供了更多字符串字面值表示法:
"string of char characters in some implementation defined encoding" - char
u8"string of utf8 chars" - char
u"string of utf16 chars" - char16_t
U"string of utf32 chars" - char32_t
L"string of wchar_t in some implementation defined encoding" - wchar_t

(转)程序猿装B指南

看到如此喜文,不转不行,同胞们乐呵乐呵,呵呵。。。

一.准备工作

“工欲善其事必先利其器。”

1.电脑不一定要配置高,但是双屏是必须的,越大越好,能一个横屏一个竖屏更好。一个用来查资料,一个用来写代码。总之要显得信息量很大,效率很高。

2.椅子不一定要舒服,但是一定要可以半躺着。

3.大量的便签,各种的颜色的,用来记录每天要完成的事务,多多益善。沿着电脑屏幕的边框,尽量贴满,显出有很多事情的样子。

4.工具书,orelly的,机械工业,电子工业什么的都可以,能英文就英文,不行影印版的也可以,反正越厚越好,而且千万不要放在书架上,一定要堆在桌上,半打开状。

二.从进门开始

0.绝对不10点以前出现在公司.

1.着装!着装!不管你是去实验室,或者去公司的大楼,在或者是小公司的民宅,或是自己创业的 黑作坊;无论是春夏秋冬白天晚上刮风下雨电闪雷鸣台风龙卷风,一个装b的程序员都要十分在意自己着装!这里只提出参考建议。初级装:衬衣+牛仔裤+休闲 鞋。中级装:T恤+宽松短裤+拖鞋。高级装:背心+宽松大花裤衩+人字拖。

2.得体的举止。在走廊以及任何形式的过道里,一定要双手插兜,走得像个痞子,至少要看起来有点反社会,如若不行,可走文弱天才型geek路线。。

3.如果有女性在你背后指指点点,小声嘀咕说这一定是一个技术男的时候,应该先低头,然后保持低头状态,缓缓回头,坏坏地蔑笑但是不要出声,然后快步前行。

4.进门后,一定不要跟任何人打招呼,笔直走向自己的位置,最多路过打一杯咖啡,千万不要有多余的动作,显示出自己的专注与心无旁骛。

三.坐下就不要再动了

1.坐下以后,姿势需要略微后仰,能翘着二郎腿最好了,然后在后仰的情况下低着头,以便看到屏幕,然后千万就不要再动了。

2.粗暴地把电脑前的大堆书推开一个口,然后摘下电脑上的一个便签,看一眼,不过3秒,可以开始coding了。

3.能不用IDE就不要用,实在装不了,无论IDE是什么,一定要调成DOS那种黑色背景的。

4.如果写前台界面,就不停地调试后台代码;如果写java,就在里面混编C;如果写C,就在里面混编汇编。不光要coding,还要时不时的翻出一本什么英文的书翻一翻,看不懂就看看插图,然后扔到面前假装懂了继续coding。

  1. 什么看起来高端就用什么,不要管实用不实用。例如对C++:switch统统重构成多态;如果有指针,统统改成智能的;C++一定要自己写 template;数字是全部要替换成宏的名字能起多长就起多长;struct就不要出现了,如果出现,也一定要用attribute修饰一下; 运算都是位操作的;操作符都是重载的;网络都是并发缓冲线程池的;int只用int32_t声明的;继承不用普通的,什么多继承虚继承 啊;helloworld也要写捕获异常的;后人一看代码,中间一堆关键字 extern,asm,auto,XXXXX_cast,volatile,explicit,register,template,让一般总在敲 int,if,else,for的小程序员顿时心生崇拜。

6.注释?算了吧。只有两个路线可以选:一,变量名起得巨长无比,看代码就和读英文文章一样顺畅,根本不需要加注释。 二,代码无比晦涩,加不加注释根本无影响。

7.千万不要用IM工具交流,千万不要问同事问题,显得自己没有水平,都是自己上网或者查书。

8.无论是同事间开玩笑或者发生任何群体性事件,不要抬头,更不要东张西望,即使地震火灾,也一定要先提交代码再行离开。

四.潇洒地离开

1.人走,主机是千万千万不能关的,至少要跑个daily build,实在不行正在svn提交也勉强算过关。

2.书应该已经又堆到屏幕前了,千万不要整理,明天再来推开。

3.不强求最后一个走,但一定要所有的非程序员,什么市场啊前台啊pm啊都走光了,才可以走。

4.走得时候一定要率性,千万不要收拾任何东西,站起来,出门,好的,就这样。

5.如果今天一定要说句话的话,找到那个最苦逼的程序员,跟他说,你进度太慢了啊,不要老让我等你。

Windows 7中系统服务进程无法使用cuda进行GPU并行计算的解决方案

最近测试提了一个Bug,原来一直正常的服务进程在新的系统中无法正常工作,现象就是显卡GPU没有正常工作。

这两天跟踪了一下问题,找到了原因,这里把具体的解决办法贴出来,方便有同样问题的朋友快速解决问题^_^。

原因分析:
Vista之后,操作系统引入了Session 0 Isolation的机制,将系统服务全部隔离到会话0中执行,但是会话0中的系统服务无法使用显卡设备,导致cuda在加载显卡驱动时失败,而无法启动GPU进行并行计算。

具体的会话0隔离机制可以参考MSDN文章:
http://msdn.microsoft.com/en-us/library/bb756986.aspx

解决方案:
找到了原因一切就好办了,从分析来看,主要是会话0中无法加载显卡驱动,所以这里需要将使用显卡的进程越狱到用户会话中,比如会话1等。

这个办法在CUDA的论坛中已经有过讨论了,这里有兄台给出了一些示例代码,可以参考:
http://forums.nvidia.com/index.php?showtopic=93450

这里说说我的具体解决方案:

  1. 在服务进程中,循环枚举可用用户会话ID
  2. 获取有效用户会话之后,获取对应用户的会话令牌
  3. 以该用户会话启动新的进程

涉及到的API如下:
通过WTSEnumerateSessions 获取所有有效会话,通过判断WTS_SESSION_INFO的State字段,获取活动会话ID
记得使用完之后,通过WTSFreeMemory释放相关内存
通过WTSQueryUserToken获取会话ID对应的会话Token
最后调用CreateProcessAsUser将进程启动到用户会话中,就可以了

总结:
其实上面的方法,相当于是延时启动,当有用户登陆之后,才启动真正的工作进程。
上述方案,需要对工程进行进程分离,将实际工作的进程独立起来,以启动到用户会话中。
有一个小问题,目前没有找到相关解决方案,有待进一步学习,有知道的朋友请分享一下^_^:
当开启UAC功能时,通过CreateProcessAsUser启动的进程无法获取管理员权限,如果工作进程需要管理员权限,可能需要关闭UAC功能才行。

Fedora 13下源码编译Mono和MonoDevelop流程总结

Fedora提供的RPM版的Mono版本比较低,为了学习体验最新版,就自己编译了一遍,整体流程比较简单,这里做个笔记记录一下。其他的一些插件就根据需要自行安装吧,走完这个流程,其他的就是小意思啦。

以下安装的版本为目前最新版(2011.5.21) Mono 2.10.2 和 MonoDevelop 2.4.2

需要下载的文件列表如下:

  • Mono运行时:mono-2.10.2.tar.bz2
  • GTK Bind:gtk-sharp-2.12.10.tar.bz2
  • GNOME Bind:gnome-sharp-2.24.1.tar.bz2
  • Mono Addins:mono-addins-0.6.1.tar.bz2
  • GDI+的Linux移植版本:libgdiplus-2.10.tar.bz2
  • MonoDevelop:monodevelop-2.4.2.tar.bz2

可以从这里进行下载:
http://ftp.novell.com/pub/mono/sources/

  1. 安装Mono运行时
tar -xvf mono-2.10.2.tar.bz2
cd mono-2.10.2
./configure --prefix=/usr
make 
make install

整个过程应该不存在大的问题

  1. 由于MonoDevelop需要其他的一些依赖库,这些库在系统中没有默认安装,Mono运行时也没有直接提供,所以这里要手动安装

安装GDI+

tar -xvf libgdiplus-2.10.tar.bz2
cd libgdiplus-2.10
./configure --prefix=/usr
make
make install
  1. 安装GTK Bind
tar -xvf gtk-sharp-2.12.10.tar.bz2
cd gtk-sharp-2.12.10
./configure --prefix=/usr
make 
make install
  1. 安装GNOME Bind

安装目前版本的GNOME Bind的时候,由于版本更新有些不同步,所以直接编译会出现Mono.GetOptions.dll找不到的错误提示,这里需要注意修正以下Makefile文件

tar -xvf gnome-sharp-2.24.1.tar.bz2
cd gnome-sharp-2.24一 
./configure --prefix=/usr

Makefile文件生成之后,这里需要修改sample相关文件的Makefile

由于这里的Mono.GetOptions.dll被开发组重命名为Mono.Options.dll,但是GNOME Bind包还没有及时更新,所以回会出现找不到该dll的问题,考虑到该dll只是在测试程序TestXfer.exe中使用,影响不大,所以这里直接注释掉TestXfer.exe的生成和运行即可。

进入子目录sample/gnomevfs,打开其中的Makefile文件,将如下几行注释掉就可以了:

注释掉221行:

EXTRA_TARGET = TestXfer.exe

注释掉449和450行:

TestXfer.exe: $(srcdir)/TestXfer.cs $(assemblies)

$(CSC) /out:TestXfer.exe $(references) -r:Mono.GetOptions.dll $(srcdir)/TestXfer.cs

然后退出子目录,进入到父目录gtk-sharp-2.12.10,继续执行:

make
make install
  1. 安装Mono Addins
tar -xvf mono-addins-0.6.1.tar.bz2
cd mono-addins-0.6.1
./configure --prefix=/usr
make
make install
  1. 安装完成相关依赖之后,就可以开始安装Monoevelop了
tar -xvf monodevelop-2.4.2.tar.bz2
cd monodevelop-2.4.2
./configure --prefix=/usr
make 
make install

截张图过来:
1.png

(转)Windows 7 下无法使用DevPartner BoundsChecker 9.1进行调试的问题

问题描述如下:

点击Start with Error Detection时回出现错误提示,显示无法打开dpinjsvc服务

进一步的错误提示如下:

CRunManager::InjectNow() - BCAX::StartRecording() FAILED: hr = 0x80004005

解决方法:

添加localhost到127.0.0.1的本地DNS映射

在%WinDir%/System32/Drivers/Etc目录中,编辑hosts文件,在末尾添加两行

127.0.0.1 localhost

::1 localhost

然后重新启动计算机即可

这是官方给出的解决方案,经测试,能够解决问题,看来BoundsChecker的机制也是基于远程调试的。。。