vc编程(vc多线程编程实例)
一、Windows多线程编程技术与实例的内容简介
本书通过众多实例介绍了如何实现Windows下的多线程编程,既重点介绍了Win32API下的多线程编程和MFC下的多线程编程,又介绍了多线程机制在网络编程、图形编程和数据库中的应用。本书每一章都从简单的多线程实例出发逐渐深入,紧紧围绕应用程序实例,向读者展示了利用多线程技术来编写高效、友好的Windows应用程序的方法,并对常用的Win32线程函数进行了深入详细的说明。本书共分8章,第l章介绍了多线程编程的基础知识;第2~5章通过实例阐明Win32下多线程的几种不同实现形式及多进程的实现机制,这是本书介绍的重点内容,也是读者学习后面几章内容所必须掌握的基础知识;第6~8章介绍了多线程技术在网络、图形处理和数据库中的应用。
本书语言通俗易懂,内容丰富翔实,突出了以实例为中心的特点,既适合具有一定c++和VC编程基础的高校相关专业学生选作多线程编程的学习用书,也适用于具有一定实际编程经验的中高级开发人员作为学习多线程编程思想的自学用书。
二、c++编程错误列表及解决方案
C++常见编译/链接错误及其解决办法
1.解决error LNK2005: ___crtExitProcess已经在 LIBCMTD.lib(crt0dat.obj)中定义
有的时候,在 Debug模式下编译没问题,换到 Release模式就发生一堆问题.
典型的例子,就是因为 c++ runtime library设定不同,所造成的重复定义连结错误.
而另一个常见的例子是专案与 library使用不同的字元集合设定
(如:一个用 Unicode Character Set,另一个用 Multi-Byte Character Set)
这个错误发生原因,有可能是
1.你 link的 lib使用 C++ Multi-threaded DLL(/MD)
2.而你的 source使用的 C++ runtime library是 Multi-threaded(/MT)
导致重复定义
解决方法:
两个使用相同的 C++ runtime library.例如都使用 static的 Multi-threaded(/MT).
2.错误 1error LNK2005:"private: __thiscall type_info::type_info(class type_info const&)"(??0type_info@@AAE@ABV0@@Z)已经在 LIBCMT.lib(typinfo.obj)中定义 MSVCRTD.lib
项目->属性-> c/C++->代码生成->运行时库设置为:多线程调试 DLL(/MDd)
被引用的库和调用的程序编译选项不同,需要改成一致后编译
3.#pragma once与#ifndef的区别
为了避免同一个文件被include多次
1#ifndef方式
2#pragma once方式
在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
方式一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
......//一些声明语句
#endif
方式二:
#pragma once
......//一些声明语句
#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况
#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
方式一由语言支持所以移植性好,方式二可以避免名字冲突
4.error LNK2019:无法解析的外部符号 __imp__PathCombineW
PathCombine是Shell api需要引入库#pragma comment( lib,"shlwapi.lib")
5.error C2662:"MyClass::GetName()”:不能将“this”指针从“const MyClass”转换为“MyClass&”
bool MyClass::operator==(const MyClass* n1) const
{return GetName()== n1->GetName();}
原因是不能在const函数中调用对象的非const方法,MyClass中的GetName()必须是const的。
6.template模板
模板声明和定义必须在同一个文件中,而且只有实例话模板类型时才编译模板实例
7.error C2275:“MyClass”:将此类型用作表达式非法 MyClass.Instance();
原因:Instance是静态方法,用.引用会出错。应该是MyClass::Instance()
8.error LNK2019:无法解析的外部符号"public: __thiscall MyClass(void)
原因:只声明了构造函数,MyClass();,但未定义。可以定义空函数,或者直接注释掉,使用默认构造函数。
9.error C2504:“testing”:未定义基类
class PackToolTest: testing.Test{}
原因:Test是testing命名空间下的一个类,需要用域操作符,testing::Test
还有一个问题,缺少基类继承权限(public、protected、private)
10.error C2864:“MyClass::_nullpack”:只有静态常量整型数据成员才可以在类中初始化
class MyClass{string _nullpack="test";}
原因:c++中,成员变量不能在声明时初始化,而是在构造函数初始化列表中先初始化
11.error LNK2019:无法解析的外部符号_WinMain@16int main()
原因:由于创建的是Win32 Project,和Win32 console Project的链接库不同
方法1:在程序最开始的地方加上以下语句
#pragma comment(linker,"/subsystem:console")
方法2:project>> setting>>在link的project options中将/subsystem:windows(console)删了
12.类似“已经在 msvcprtd.lib(MSVCP80D.dll)中定义”问题
vs2005 Debug/Release需要分别配制
分析一下错误来源,会发现:
1.错误来源主要是重复定义的问题,而且重复定义的基本上都是VC Runtime和Standard C++ Library中的函数
2. LIBCMT和LIBCPMT为Release下的Lib,本来不应该出现在Debug版本的链接的Lib中
3.重复定义的问题主要出现在:LIBCMT, LIBCPMT, MSVCPRTD, MSVCRTD
来看看出问题的LIB是那些:
1. LIBCMT:C Runtime库的多线程静态链接的Release版本
2. LIBCPMT:C++ Standard Library的多线程静态链接的Release版本
3. MSVCPRTD:C++ Standard Library的多线程DLL的Debug版本
4. MSVCRTD:C Runtime Library的多线程DLL的Debug版本
当前我们的配置是多线程DLL的Debug版,因此3和4是应该出现在link的列表中的,不属于多余。而后两者则是只是当多线程静态链接Release版中才会出现。这提示我在项目中加入的ANTLR.LIB可能是造成这个问题的根源,因为静态库的编译选项很容易和主程序发生冲突,并且根据实际信息我们可以看出ANTLR.LIB应该是用多线程静态链接的Release版本来编译的。
解决方法:
1、首先查看编译项目依赖的其他项目的运行时库是否一致
2、如果不一致,改为同样的运行时库,如在下编译的是:“多线程调试 DLL(/MDd)”,现在需要把所有的依赖项目的运行时库都改为一致的库,就OK了。
13.error C2143:语法错误:缺少“;”(在“*”的前面)
原因:产生错误处,某类型未include,可能头文件名拼写错误、头文件名已更改
14.error C2572:“MyClass::Invoke”:重定义默认参数:参数 2
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type= ASYN)
原因:默认参数,只需在声明时指定。方法定义的时候无需指定默认参数。
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type/*= ASYN*/)
{...}。。。。。
希望对你有用