GTEST基础学习


1 安装与配置

1.1 编译gtest:

下载gtest1.7.0版本,(本人通过CSDN下载),解压后,文件目录下图所示:


打开msvc文件夹,打开gtest或gtest_md工程文件。进行编译。

编译方法:

如果需要生成动态库(DLL),则需要3步:1.将“配置类型”改为“动态库”。2.修改编译宏定义:

gtest->属性->配置属性->C/C++->预处理器->预处理器定义,将_LIB改为_USRDLL,并添加宏GTEST_CREATE_SHARED_LIBRARY=1。3.修改运行时库,将 gtest->属性->配置属性->C/C++->代码生成->运行库,改为MDd。

编译完毕后,会在$GTEST_ROOT\gtest\debug目录下生成gtestd.lib静态库文件.为了方便编写单元测试代码,在$GTEST_ROOT目录下新建lib目录,将我们刚才生成的gtestd.lib拷贝到$GTEST_ROOT\lib目录下。

编译之后,在msvc里面的Debug或是Release目录里看到编译出来的gtestd.lib或是gtest.lib文件。

在根目录下,新建lib文件夹,将lib文件放入。

 

1.2 配置gtest:

建立工程后,分别配置gtest的include路径、lib路径和Runtime Library。

 



第一:在Release和Debug模式下编译GTest,分别生成gtest.lib和gtestd.lib

在我们新建的使用GTest测试的工程中,Release和Debug模式要分别使用上面两个对应的lib文件。

第二:设置好我们的工程的代码生成(属性Properties-->C++-->代码生成Code Generation)中的运行时库(Runtime Library)。

Release模式为:Multi-threaded( /MT)

Debug模式为:Muti-threadedDebug(/MTd)

在本次使用中,选用的时MDd模式,即多线程调试DLL。

 

2 使用方法

测试Demo:

#include <gtest/gtest.h>

int Foo(int a,int b)

{

       if(0 == a||0 == b)

              throw "don't do that";

       int c = a%b;

       if (0 == c)

       {

              return b;

       }

       return Foo(b,c);

}

TEST(FooTest,HandleNoneZeroInput)

{

       EXPECT_EQ(2,Foo(4,10));

       EXPECT_EQ(6,Foo(30,18));

}

int main(int argc, _TCHAR* argv[])

{

       testing::InitGoogleTest(&argc,argv);

       return RUN_ALL_TESTS();

}

 

2.1 断言

断言主要分为ASSERT和EXPECT两个系列。

1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。

2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。

例:

// int型比较,预期值:3,实际值:Add(1, 2)

EXPECT_EQ(3, Add(1, 2));

//

当实际值与预期值不相等时会输出error。

为了能更好的识别,可以使用<<操作符自定义输出:

如:EXPECT_EQ(x[i], y[i]) << "Vectorsx and y differ at index " << i;//在输出时将会输出这句话。

 

布尔值检查

Fatal assertion

Nonfatal assertion

       Verifies

ASSERT_TRUE(condition);

EXPECT_TRUE(condition);

condition is true

ASSERT_FALSE(condition);

EXPECT_FALSE(condition);

condition is false

 

数值型数据检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_EQ(expected, actual);

EXPECT_EQ(expected, actual);

expected == actual

ASSERT_NE(val1, val2);

EXPECT_NE(val1, val2);

val1 != val2

ASSERT_LT(val1, val2);

EXPECT_LT(val1, val2);

val1 < val2

ASSERT_LE(val1, val2);

EXPECT_LE(val1, val2);

val1 <= val2

ASSERT_GT(val1, val2);

EXPECT_GT(val1, val2);

val1 > val2

ASSERT_GE(val1, val2);

EXPECT_GE(val1, val2);

val1 >= val2

 

字符串检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_STREQ(expected_str, actual_str);

EXPECT_STREQ(expected_str, actual_str);

the two C strings have the same content

ASSERT_STRNE(str1, str2);

EXPECT_STRNE(str1, str2);

the two C strings have different content

ASSERT_STRCASEEQ(expected_str, actual_str);

EXPECT_STRCASEEQ(expected_str, actual_str);

the two C strings have the same content, ignoring case

ASSERT_STRCASENE(str1, str2);

EXPECT_STRCASENE(str1, str2);

the two C strings have different content, ignoring case

 

其中:

*STREQ*和*STRNE*同时支持char*和wchar_t*类型的,*STRCASEEQ*和*STRCASENE*只接收char*。

显示返回成功或失败

直接返回成功:

SUCCEED();

返回失败:

Fatal assertion

Nonfatal assertion

FAIL();

ADD_FAILURE();

 

异常检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_THROW(statement, exception_type);

EXPECT_THROW(statement, exception_type);

statement throws an exception of the given type

ASSERT_ANY_THROW(statement);

EXPECT_ANY_THROW(statement);

statement throws an exception of any type

ASSERT_NO_THROW(statement);

EXPECT_NO_THROW(statement);

statement doesn't throw any exception

 

 

谓词断言

在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_PRED1(pred1, val1);

EXPECT_PRED1(pred1, val1);

pred1(val1) returns true

ASSERT_PRED2(pred2, val1, val2);

EXPECT_PRED2(pred2, val1, val2);

pred2(val1, val2) returns true

...

...

...

 

还可以自定义输出格式,通过如下:

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_PRED_FORMAT1(pred_format1, val1);`

EXPECT_PRED_FORMAT1(pred_format1, val1);

pred_format1(val1) is successful

ASSERT_PRED_FORMAT2(pred_format2, val1, val2);

EXPECT_PRED_FORMAT2(pred_format2, val1, val2);

pred_format2(val1, val2) is successful

...

...

...

注意:pred_format的返回值必须testing::AssertionResult(),这个返回值相当于bool类型,当成功是,返回testing::AssertionSuccess()testing::AssertionFailure();

 

浮点型检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_FLOAT_EQ(expected, actual);

EXPECT_FLOAT_EQ(expected, actual);

the two float values are almost equal

ASSERT_DOUBLE_EQ(expected, actual);

EXPECT_DOUBLE_EQ(expected, actual);

the two double values are almost equal

 

对相近的两个数比较:

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_NEAR(val1, val2, abs_error);

EXPECT_NEAR(val1, val2, abs_error);

the difference between val1 and val2 doesn't exceed the given absolute error

 

2.2 事件机制

gtest的事件一共有3种:

1. 全局的,所有案例执行前后。

2. TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后。

3. TestCase级别的,每个TestCase前后。

全局事件

必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。

1. SetUp()方法在所有案例执行前执行

2. TearDown()方法在所有案例执行后执行

TestSuite事件

需要写一个类,继承testing::Test,然后实现两个静态方法

1. SetUpTestCase() 方法在第一个TestCase之前执行

2. TearDownTestCase() 方法在最后一个TestCase之后执行

TestCase事件

TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

1. SetUp()方法在每个TestCase之前执行

2. TearDown()方法在每个TestCase之后执行

 

2.3 参数化测试

参数化测试提供了简化的参数测试方法,可以一次性的测试多组参数,而不用编写重复性的代码。

首先,必须添加一个类,继承testing::TestWithParam<T>,其中T就是你需要参数化的参数类型,比如上面的例子,我需要参数化一个int型的参数

class IsPrimeParamTest :public::testing::TestWithParam<int>

{

 

};

其次,告诉gtest你拿到参数的值后,具体做些什么样的测试。这里,要使用一个新的宏TEST_P,在TEST_P宏里,使用GetParam()获取当前的参数的具体值。

TEST_P(IsPrimeParamTest,HandleTrueReturn)

{

   int n =  GetParam();

   EXPECT_TRUE(IsPrime(n));

}

最后,使用INSTANTIATE_TEST_CASE_P这宏来告诉gtest你要测试的参数范围:

INSTANTIATE_TEST_CASE_P(TrueReturn,IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));

第一个参数是测试案例的前缀,可以任意取。

第二个参数是测试案例的名称,需要和之前定义的参数化的类的名称相同,如:IsPrimeParamTest

第三个参数是可以理解为参数生成器,上面的例子使用test::Values表示使用括号内的参数。Google提供了一系列的参数生成的函数:

Range(begin, end[, step])

范围在begin~end之间,步长为step,不包括end

Values(v1, v2, ..., vN)

v1,v2到vN的值

ValuesIn(container) and ValuesIn(begin, end)

从一个C类型的数组或是STL容器,或是迭代器中取值

Bool()

取false 和 true 两个值

Combine(g1, g2, ..., gN)

它将g1,g2,...gN进行排列组合,g1,g2,...gN本身是一个参数生成器,每次分别从g1,g2,..gN中各取出一个值,组合成一个元组(Tuple)作为一个参数。

说明:这个功能只在提供了<tr1/tuple>头的系统中有效。gtest会自动去判断是否支持tr/tuple,如果你的系统确实支持,而gtest判断错误的话,你可以重新定义宏GTEST_HAS_TR1_TUPLE=1

2.4 死亡测试

死亡测试即对程序的崩溃进行检测。

死亡测试的测试用例名称(test_case_name)规定要以DeathTest结尾,因为gtest优先运行死亡测试。

需要注意的是,DeathTest在*NIX环境下才会自动产生内存转储文件(core文件),windows下需要进行设置。

致命断言

非致命断言

说明

ASSERT_DEATH(statement, regex`);

EXPECT_DEATH(statement, regex`);

statement是引起程序崩溃的代码语句。

regex是一个正则表达式,用来匹配异常时在stderr中输出的内容,当不指定regex的时候,传入空字符串””。

ASSERT_DEATH_IF_SUPPORTED(statement, regex`);

EXPECT_DEATH_IF_SUPPORTED(statement, regex`);

如果当前系统支持死亡测试,则按照*_DEATH的方式运行死亡测试,否则不做检查

ASSERT_EXIT(statement, predicate, regex`);

EXPECT_EXIT(statement, predicate, regex`);

……

 

*_EXIT(statement, predicate, regex`)

1. statement是被测试的代码语句

2. predicate 在这里必须是一个委托,接收int型参数,并返回bool。只有当返回值为true时,死亡测试案例才算通过。gtest提供了一些常用的predicate:

 

testing::ExitedWithCode(exit_code)

如果程序正常退出并且退出码与exit_code相同则返回true

testing::KilledBySignal(signal_number) // Windows下不支持

如果程序被signal_number信号kill的话就返回true

3. regex是一个正则表达式,用来匹配异常时在stderr中输出的内容

注意:*_DEATH其实是对*_EXIT进行的一次包装,*_DEATHpredicate判断进程是否以非0退出码退出或被一个信号杀死。

例子:

TEST(ExitDeathTest, Demo)

{

   EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");

}

注意:ASSERT_EXIT(EXPECT_EXIT)断言要求程序的退出码与pred中的exitcode一致,否则断言失败,修改一下上面的例子:

 

死亡测试运行方式

1. fast方式(默认的方式)

testing::FLAGS_gtest_death_test_style= "fast";

2. threadsafe方式

testing::FLAGS_gtest_death_test_style= "threadsafe";

 

Trace跟踪:

SCOPE_TRACE(message)

SCOPE_TRACE需要与{ }作用域符号一起使用,在作用域内失败的断言,都会打上SCOPE_TRACE中定义的跟踪信息。还是举例说明。

TEST(SubRoutingTest,HaveScopeAssert)

{

       {

              SCOPED_TRACE("errorhere"); 

              SubTest(9);

       }

       SubTest(2);

}

在测试循环体时,可加入标志,表示在那一次循环时出现的问题。

测试demo:

#include <gtest/gtest.h>

#include<gtest/gtest-death-test.h>

void demo()

{

       int*p = NULL;

       *p= 30;

       SCOPED_TRACE("errorhere");//定义trace跟踪

}

 

TEST(demoDeathTest,hahaha)

{

       EXPECT_DEATH(demo(),"");//测试demo是否会引起崩溃

}

TEST(exitDeathTest,yes)

{

       testing::FLAGS_gtest_death_test_style= "threadsafe";//设置死亡测试的运行方式是threadsafe

       EXPECT_EXIT(_exit(1),testing::ExitedWithCode(1),"");//测试退出值是否一致

}

int main(int argc, char* argv[])

{

       testing::InitGoogleTest(&argc,argv);

       returnRUN_ALL_TESTS();

}

运行结果:


疑问:当使用预编译模式下的int _tmain(int argc,_TCHAR* argv[])时,使用gtest测试会出现死循环。(typedef wchar_t _TCHAR)

测试:当注释掉所有TEST后,执行正常,当存在TEST时,即出现死循环。

2.5 运行参数

对于运行参数,gtest提供了三种设置的途径:

1. 系统环境变量

2. 命令行参数

3. 代码中指定FLAG

因为提供了三种途径,就会有优先级的问题, 有一个原则是,最后设置的那个会生效。不过总结一下,通常情况下,比较理想的优先级为:

命令行参数 > 代码中指定FLAG > 系统环境变量

注:在gtest中,在测试套件或者测试用例,测试夹具的命名的前面加上DISABLED_gtest认为这样的测试是被禁用了的。

运行标志

testing::GTEST_FLAG宏中,指定要设置的标志,例如:

 testing::GTEST_FLAG(output) = "xml";

运行标志必须要在testing::InitGoogleTest(&argc, argv);执行前设置。

官方文档中介绍了的运行标志如下:

运行标志

说明

filter

同--gtest_filter

also_run_disabled_tests

同---gtest_also_run_disabled_tests

repeat

同--gtest_repeat(--gtest_repeat=[COUNT])

color=(yes|no|auto)

同---gtest_color=(yes|no|auto) 默认auto

print_time

同---gtest_print_time(gtest_print_time=0或1)默认打印

output

同---gtest_output(--gtest_output=xml:d:\foo.xml 指定输出到d:\foo.xml)

break_on_failure

同---gtest_break_on_failure

catch_exceptions

同---gtest_catch_exceptions

测试demo:

#include <gtest/gtest.h>

#include <iostream>

using namespace std;

void demo()

{

       inti = 0;

       while(i!= 10)

       {++i;}

}

TEST(demoDEATHTEST,hahaha)

{

       EXPECT_DEATH(demo(),"")<<"sosurprised,why?";

}

TEST(demoTEST,heiheihei)

{

       EXPECT_EXIT(_exit(1),testing::ExitedWithCode(1),"");

}

int main(int argc, char* argv[])

{

       testing::FLAGS_gtest_death_test_style= "fast";

       testing::GTEST_FLAG(output)= "xml";//写在InitGoogleTest之前

       testing::GTEST_FLAG(color)= "yes";//设置颜色为彩色

       testing::GTEST_FLAG(repeat)= 2;//设置测试重复2次

       testing::InitGoogleTest(&argc,argv);

       returnRUN_ALL_TESTS();

}

结果:

 

3 遇到的问题:

1.在vs2008中无法打开GTEST中的“msvc”中的gtest解决方案。

问题提示:



a)解决方法:

b)修改sln文件,按附录后的diff文件修改对应的sln文件。

c)修改vcproject文件,按附录后的diff文件修改所有的vcproject文件。

2.编译gtest.sln出错(gtest_prod_test、gtest_unittest会出错):

a)解决方法:

b)属性,配置属性,C/C++,代码生成,运行库,多线程调试(/MTd)。

c)属性,配置属性,链接器,命令行,附加选项:,添加“/NODEFAULTLIB:libCMT”。

 

4 附录:

修改gtest.sln文件(-号表示删去,+号表示添加)

-Microsoft Visual Studio Solution File, Format Version8.00

+Microsoft Visual Studio Solution File, Format Version10.00

+# Visual Studio 2008

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest", "gtest.vcproj","{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_main", "gtest_main.vcproj","{3AF54C8A-10BF-4332-9147-F68ED9862032}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_unittest", "gtest_unittest.vcproj","{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_prod_test", "gtest_prod_test.vcproj","{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Global

-        GlobalSection(SolutionConfiguration)= preSolution

-                 Debug = Debug

-                 Release = Release

+       GlobalSection(SolutionConfigurationPlatforms)= preSolution

+                Debug|Win32 = Debug|Win32

+                Release|Win32 = Release|Win32

        EndGlobalSection

-        GlobalSection(ProjectConfiguration)= postSolution

-                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg= Debug|Win32

-                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0= Debug|Win32

-                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg= Release|Win32

-                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0= Release|Win32

-                 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg= Debug|Win32

-                 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0= Debug|Win32

-                 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg= Release|Win32

-                 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0= Release|Win32

-                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg= Debug|Win32

-                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0= Debug|Win32

-                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg= Release|Win32

-                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0= Release|Win32

-                 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg= Debug|Win32

-                 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0= Debug|Win32

-                 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg= Release|Win32

-                 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0= Release|Win32

+       GlobalSection(ProjectConfigurationPlatforms)= postSolution

+                {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg= Debug|Win32

+                {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0= Debug|Win32

+                {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg= Release|Win32

+                {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0= Release|Win32

+                {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg= Debug|Win32

+                {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0= Debug|Win32

+                {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg= Release|Win32

+                {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0= Release|Win32

+                {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|Win32.ActiveCfg= Debug|Win32

+                {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug|Win32.Build.0= Debug|Win32

+                {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|Win32.ActiveCfg= Release|Win32

+                {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release|Win32.Build.0= Release|Win32

+                {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|Win32.ActiveCfg= Debug|Win32

+                {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug|Win32.Build.0= Debug|Win32

+                {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|Win32.ActiveCfg= Release|Win32

+                {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release|Win32.Build.0= Release|Win32

        EndGlobalSection

-        GlobalSection(ExtensibilityGlobals)= postSolution

+       GlobalSection(SolutionProperties)= preSolution

+                HideSolutionNode = FALSE

        EndGlobalSection

-        GlobalSection(ExtensibilityAddIns)= postSolution

-        EndGlobalSection

 EndGlobal

 

修改gtest_md.sln文件(-号表示删去,+号表示添加)

-Microsoft Visual Studio Solution File, Format Version8.00

+Microsoft Visual Studio Solution File, Format Version10.00

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest-md", "gtest-md.vcproj","{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_main-md", "gtest_main-md.vcproj","{3AF54C8A-10BF-4332-9147-F68ED9862033}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_prod_test-md", "gtest_prod_test-md.vcproj","{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")= "gtest_unittest-md", "gtest_unittest-md.vcproj","{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"

-        ProjectSection(ProjectDependencies)= postProject

-        EndProjectSection

 EndProject

 Global

-        GlobalSection(SolutionConfiguration)= preSolution

+       GlobalSection(SolutionConfigurationPlatforms)= preSolution

                 Debug= Debug

                 Release= Release

        EndGlobalSection

-        GlobalSection(ProjectConfiguration)= postSolution

+       GlobalSection(ProjectConfigurationPlatforms)= postSolution

                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg= Debug|Win32

                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0= Debug|Win32

                 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg= Release|Win32

@@ -38,8 +30,7 @@ Global

                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg= Release|Win32

                 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0= Release|Win32

        EndGlobalSection

-        GlobalSection(ExtensibilityGlobals)= postSolution

+       GlobalSection(SolutionProperties)= preSolution

+                HideSolutionNode = FALSE

        EndGlobalSection

-        GlobalSection(ExtensibilityAddIns)= postSolution

-        EndGlobalSection

 EndGlobal

 

修改msvc中各*.vcproj文件(-号表示删去,+号表示添加)

-        Version="7.10"

+       Version="9.00"

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聊聊技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值