2013年4月

fatal error C1010: unexpected end of file while looking for precompiled header directive

问题

某项目中加入一个别人写好的类,叫做 netadapter。 netadapter有两个文件 netadapter.h 和 netadapter.cpp 。 将netadapter.h在stdafx.h预编译头文件中包含。编译出错:netadapter.cpp(384) : fatal error C1010: unexpected end of file while looking for precompiled header directive。

原因

一般情况下。netadapter.cpp的类声明放在netadapter.h,所以 netadapter.cpp #include了netadapter.h。但是此时的情况是netadapter.h已经在stdafx.h中包含。编译器在netadapter.cpp中没有查找到预编译头文件指令。其实预编译头文件指令就是:#include <stdafx.h>

解决

在netdapter.cpp的首行加入#include <stdafx.h>,再编译一次,通过!如果我们将 #include "netadapter.h"注释掉,同样编译通过了!

PS:网上有些朋友的做法是不使用预编译头文件(PCH)。这个可以起作用。不过没有了PCH,每次编译都比较耗时!!

identifier was truncated to '255' characters in the debug information

问题

VC项目加入了头文件出现如下报错:

D:\vs6\VC98\INCLUDE\vector(60) : warning C4786: 'std::vector<std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >,std::allocator<std::basic_string<unsigned short,std::char_traits<unsigned short>,std::all
ocator<unsigned short> > > >::~vector<std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >,std::allocator<std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> 
> > >' : identifier was truncated to '255' characters in the debug information

原因

这些警告的意思是,某些标识符太长了,超过255个字符, 在debug显示的时候会被截断。 这个警告没办法解决的, 所以就不要在意了。VC6对STL的一些不完全支持造成。这是因为VC6对新标准支持力度不够,STL中的map等等的实现中名字过长,被VC6截断了.就是说因为用了模板库导致标识符过长,VC就出了警告。这可以看做是VC的一个BUG。

解决方法

为在源文件头部加入一下预编译代码

#ifdef WIN32
#pragma warning (disable: 4514 4083 4786)
#endif

这样可以关掉这个warning(当然这只是让他不显示而已)。有些人说加上了以上忽略警告的代码。但是还是会报错。那是因为你#include了的头文件被#include到了stdafx.h预编译头文件当中。需要在stdafx.h头几行加上以上代码。

此警告貌似现在MSDN上有只有针对WINCE 5.0平台的解释。不过是一个意思。

Compiler Warning (level 1) C4786 (Windows CE 5.0)


Windows CE 5.0


'identifier' : identifier was truncated to 'number' characters in the debug information

The identifier string exceeded the maximum allowable length and was truncated.

The debugger cannot debug code with symbols longer than 255 characters. In the debugger, you cannot view, evaluate, update, or watch the truncated symbols.

This limitation can be overcome by shortening identifier names. The example code below demonstrates this method.

A trace mechanism can also be used to solve this problem. A trace mechanism is like the printf statements in the code. It keeps track of what is going on in an application during the debugging process.

The _ASSERT_ASSERTE_RPTn and _RPTFn macros provide concise and flexible ways to perform the trace. These macros are not defined when _DEBUG is not defined.

The example below demonstrates a situation that would cause this compiler warning to occur, and the solution to this problem.



 //sample1.cpp
 //In this program we have a class of a very long name.
 //We instantiate an object of that class type. We will
 //get multiple C4786 warnings. The comments below
 //demonstrate the solution to this problem.

 #define a_really_long_class_name 
a_really_really_really_really_really_really_really_really_really_really_
really_really_really_really_really_really_really_really_really_really_
really_really_really_really_really_really_really_really_really_really_
really_really_really_really//_really_long_class_name

 //SOLUTION: Uncomment the lines below

 //#ifdef _DEBUG
 //#define a_really_long_class_name A_SHORT_CLASS_NAME
 //#endif

 class a_really_long_class_name
 {
 public:
a_really_long_class_name() {};
int m_data;
 };

 void main()
 {
 a_really_long_class_name test_obj;
 test_obj.m_data = 12;
 }

The following example demonstrates that templates with some long class names as their parameters can easily exceed the 255 character limit. Solutions to the problem are also provided.



 //sample2.cpp
 //SOLUTION1: uncomment the next 4 lines
 //#ifdef _DEBUG
 //#define VeryLongClassNameA A
 //#define VeryLongClassNameB B
 //#endif

 //SOLUTION2: An alternative solution:
 //uncomment the next 3 lines.
 //#ifdef _DEBUG
 //#define SomeRandomClass SRC
 //#endif

 template <class A1, class A2, class A3, class A4>
 class VeryLongClassNameA{};

 template <class B1, class B2, class B3>
 class VeryLongClassNameB{};

 template <class C1, class C2>
 class VeryLongClassNameC{};

 template <class D1>
 class VeryLongClassNameD{};

 class SomeRandomClass{};

 typedef VeryLongClassNameD<SomeRandomClass> ClassD ;
 typedef VeryLongClassNameC<SomeRandomClass, ClassD> ClassC;
 typedef VeryLongClassNameB<SomeRandomClass, ClassC, ClassD> ClassB;
 typedef VeryLongClassNameA<SomeRandomClass, ClassB, ClassC, ClassD> ClassA;

 void SomeRandomFunction(ClassA aobj){}

 void main()
 {
ClassA AObj ;
SomeRandomFunction(AObj) ;
 }


让WordPress插件Simple Tags 2.2支持中文支持没有空格tag的匹配

Simple Tags是 Wordpress 功能强大的Tag插件。但是对中文支持欠佳。通过手动的修改一下代码,可以让它更完美的支持中文。

第一步,找到 \inc\class.client.autoterms.php 文件,在大约第100行,

将类似如下语句:

if ( preg_match("/\b".$term."\b/i", $content) );

中的两个 \b 去掉,\b 在正则表达式中表示单词边界,但是中文跟英文不一样,字(单词)与字(单词)之间没有边界。即:

if ( preg_match("/".$term."/i", $content) );

第二步,找到 \inc\class.client.autolinks.php 文件,在大约第160行,

将类似如下语句的行首添加双斜杠,将这两句话注释掉:

//$match = '/(\PL|\A)(' . preg_quote($term_name, "/") . ')(\PL|\Z)/u'.$case; 
//$substitute = '$1<a href="'.$term_link.'" class="st_tag internal_tag" '.$rel.' title="'. esc_attr( sprintf( __('Posts tagged with %s', 'simpletags'), $term_name ) )."\">$2</a>$3";

然后将紧跟在下面的原本被注释掉的语句启用,并去掉其中的两个 \b ,即:

$match = "/" . preg_quote($term_name, "/") . "/".$case;
$substitute = '<a href="'.$term_link.'" class="st_tag internal_tag" '.$rel.' title="'. esc_attr( sprintf( __('Posts tagged with %s', 'simpletags'), $term_name ) )."\">$0</a>";

好了,现在就OK了。

修改Vmware Workstation虚拟机物理硬盘序列号ID

有些软件的注册机制是根据物理硬盘序列号来作为唯一的标识符。此序列号写在硬盘的固件里面。一般的方法是无法修改此序列号的。

如果需要无限试用软件可以让软件在虚拟机内运行。试用期到了之后修改硬盘物理序列号好可以继续试用。

修改方法:

用winhex打开vmware-vmx.exe,如果是32位直接打开vmware程序下的vmware-vmx.exe,64位在x64目录下vmware-vmx.exe。搜索:“00000000000000000001”(18位字符串,不是hex),这个是vmware默认的硬盘序列号。修改为其他的,比如“00000000000000000002”,然后保存重新打开虚拟机。发现序列号已经发生改变。

修改Vmware Workstation虚拟机物理硬盘序列号ID

关于LoadLibrary return 126 路径问题

假设有一个程序main.exe需要动态调用此程序的一个子目录subfolder1下的一个dll。命名为1.dll。然后1.dll动态调用了同级目录下的2.dll。

文件结构如下:

main.exe
subfolder1
├─1.dll
└─2.dll

那么1.dll用LoadLibrary指定DLL路径的时候需要加上subfolder1,不然报错126找不到指定模块。

LoadLibrary("2.dll") -> ×
LoadLibrary("subfolder\\2.dll") -> √