2008年1月14日星期一

cygwin,在win中开发linux程序

cygwin,在win中开发linux程序
作者:乾坤一笑 CSDN (2005-04-06 17:17:39)

很多用windows的朋友不习惯于用linux的开发环境。虽然很乐意尝试一下,但是往往怕 linux系统打乱了自己的正常生活:1〉装linux系统把windows系统给搞坏了,导致自己无法正常生活;2>linux开发上手太难,写出第一个helloworld不亚于java的难度,环境配置摸不着头脑。对于此,我的看法是:路不管平还是陡,终归你要走的,如果你愿意投入到 linux开发的社群中来,不会安装linux系统,不会配置工作环境是不能想象的。(事实上,确实要了解很多东西的原理,不然很难排错:诸如,硬盘引导器的引导原理、分区结构原理及linux分区结构和文件系统、环境变量的设置、种类繁多的压缩包安装包的解压安装方法、用户管理权限管理等常用命令、以至于驱动安装系统中文化等等异常琐碎的东东)。

本文试图跳过这个难走的步骤,启用一个win环境下的linux仿真器(和linux下面的命令行开发环境基本一致),用短短的20分钟的时间,教你做出一个纯正的linux下gcc编译的helloworld。就象是买点心前先尝尝味道,不也是一件很愉快的事情么?(注:cygwin事实上不仅有此模拟功能,它也是移植unix<-->win程序的一个很有效的工具,也有人用它来做嵌入式系统开发)

一、cygwin是什么?
这个问题你最好google一下"cygwin的历史",或许能够获得更为详尽的答案。简而言之,cygwin是一个在windows平台上运行的 linux模拟环境,是cygnus solutions公司开发的自由软件(该公司开发了很多好东西,著名的还有eCos,不过现已被Redhat收购)。插一句废话,很多朋友不明白 linux和unix的区别和联系,在此也简要介绍一下。UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统; linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统。为什么linux和unix之间有很多软件可以很轻松的移植?因为linux也满足POSIX规范,所以在运行机制上跟unix相近。
以下引用网上的一段话(出处:http://blog.csdn.net/glock18/archive/2004/07/10/38275.aspx),
用于说明cygwin的工作机制:cygnus当初首先把gcc,gdb,gas等开发工具进行了改进,使他们能够生成并解释win32的目标文件。然后,他们要把这些工具移植到windows平台上去。一种方案是基于win32 api对这些工具的源代码进行大幅修改,这样做显然需要大量工作。因此,他们采取了一种不同的方法――他们写了一个共享库(就是cygwin dll),把win32 api中没有的unix风格的调用(如fork,spawn,signals,select,sockets等)封装在里面,也就是说,他们基于 win32 api写了一个unix系统库的模拟层。这样,只要把这些工具的源代码和这个共享库连接到一起,就可以使用unix主机上的交叉编译器来生成可以在 windows平台上运行的工具集。以这些移植到windows平台上的开发工具为基础,cygnus又逐步把其他的工具(几乎不需要对源代码进行修改,只需要修改他们的配置脚本)软件移植到windows上来。这样,在windows平台上运行bash和开发工具、用户工具,感觉好像在unix上工作。关于cygwin实现的更详细描述,请参考http://cygwin.com/cygwin-ug-net/highlights.html

二、cygwin的安装。
cygwin的安装文件很容易通过google找到。目前国内的网站上有"网络安装版"和"本地安装版"两种。标准的发行版应该是 网络安装版。两者并无大不同,下面介绍一下安装的过程。

step1. 下载后,点击安装文件(setup.exe)进行安装,第一个画面是GNU版权说明,点"下一步(N)―>",
进入安装模式选择画面。

step2. 安装模式有"Install from Internet"、"Download form Internet"、
"Install from Local Directory" 三种。"Install form Internet"就是直接从internet上装,适用于网速较快的情况。如果你和我一样网速不是很快,或者说装过之后想把下载的安装文件保存起来,下次不再下载了直接安装,就应该选择"Download form Internet",下载安装的文件(大约40M左右)。
事实上,所谓的"本地安装版",也是别人从网上下载全部文件后打的包(适用于中国国情嘛^_^)

step3. 接下来是选择安装目的路径和安装源文件所在的路径,之后就进入了选择安装包所在的路径。
注意了阿,这里可是重头戏。我第一安装的时候就是没有看清这一步,结果没有把gcc装进去,导致没法编译文件。
+ All Default
+ Admin Default
....
+ Devel Default
+ Editors Default
....
如上图所示,你在这个TreeView的某个节点上双击,就可以改变它的状态,如Default、Install、Uninstall、Reinstall四种状态。默认的都是Default状态,很多工具的默认状态都是不安装。
在这里我选择了在All这一行上后面的Default上点Install,全部安装,以免后患。(注意:这里的树形控件和win下面的不同,你试试点在All上点 和 在All这一行后面的Default上点,会有不同的响应)

step4. 点下一步,安装成功。它会自动在你的桌面上建立一个快捷方式。

好了,下面就开始我的linux旅程了。双击cygwin的快捷方式进入系统。
首先介绍几个简单的linux命令。
pwd 显示当前的路径
cd 改变当前路径,无参数时进入对应用户的home目录
ls 列出当前目录下的文件。此命令有N多参数,比如ls -al
ps 列出当前系统进程
kill 杀死某个进程
mkdir 建立目录
rmdir 删除目录
rm 删除文件
mv 文件改名或目录改名
man 联机帮助
less 显示文件的最末几行

由于linux下面的命令大多都有很多参数,可以组合使用。所以,每当你不会或者记不清楚改用那个参数,那个开关的时候,可以用man来查找,比如,我想查找ls怎么使用,可以键入
$ man ls
系统回显信息如下:
LS(1) FSF LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by
default). Sort entries alphabetically if none of -cftuSUX
nor --sort.
-a, --all
do not hide entries starting with .
-A, --almost-all
do not list implied . and ..
-b, --escape
print octal escapes for nongraphic characters
--block-size=SIZE
use SIZE-byte blocks
:
很全是吧,嘿嘿。

好了,多说无意,让我们

Cygwin的安装

1.1 2.1. Cygwin是可以在Windows下执行的Linux运行环境


本来我是安装了Linux10,但是使用过程中还是需要经常回到windows查看一些文档啊、拷贝一些文件啊,太烦了,所以呢还是决定把Cygwin搞起来,这样在windows下工作就方便多了。

Cygwin的安装有两种方法:

一种是直接在线安装,这是按配置需要下载的,但是下载的东西会很多很大,400M左右,需要的时间比较长。

第二种是先到macraigor下载一个安装包,60多M,下载速度很快。安装选项也简单。然后再执行在线安装,安装Ncurses libraries就可以了。

我开始使用第一种方法,搞了几天,重复了很多次,可老是安装不好,最后还是用第二种方法搞定的。


1.2 2.2. 下载


1.2.1 2.2.1. CYGWIN(2.0.0)

See document: http://www.macraigor.com/full_gnu.htm <http://www.macraigor.com/full_gnu.htm>

60M.下载速度很快,我用ADSL下载速度达到70多K,比一般下载得快多了,不过我是后半夜下载的。:)

1.3 2.3. 安装

从macraigor下载的Cygwin2.0直接安装就可以了,安装过程很简单。但是似乎缺少一个组件Ncurses libraries,在make menuconfig的时候会报错,需要执行在线安装的步骤添加这个组件。


1.4 2.4. 在线安装

1.4.1 2.4.1. 下载setup.exe

See document: www.cygwin.com <outbind://1/www.cygwin.com>

登陆www.cygwin.com,页面上有一个Install Cygwin Now的连接,是一个setup.exe文件,直接打开也可以,推荐下载下来,存到一个目录里,这样可以把文件下载下来,以后安装就方便了。


1.4.2 2.4.2. 安装选项

必须安装的子目录(sub category): (把子目录旁边的"default"用鼠标点一下,直到变成"install")
Archive
Base
Devel:包括gcc、make等编译工具
Libs
Net
DEShells
Utils: 包括bzip2等实用工具

如果是已经从macraigor下载安装了Cygwin,那么选择安装 Devel下的libncurses-devel一项就可以了。

大家可选择较快的下载地址,我是用的mirrors.rcn.net,下载速度在20k左右。


必须通过cygwin提供的setup.exe进行安装,可根据安装提示一步一步进行,提供通过internet安装方式或本地安装方式。建议把cygwin整个安装包下载到本地再进行本地安装比较方便。如果无特殊需求,可简单按它的缺省安装方式安装最少数量的软件包。建议不要安装到c:\下。cygwin的问题和解答可参考cygwin FAQ。


1.5 设置

1.5.1 批处理文件


在自己生成交叉编译器之前,首先对Cygwin进行一些设置。假设Cygwin安装在e目录下,在打开Cygwin窗口之前,进入到E:\Cygwin目录。在这个目录下,有一个文件名为Cygwin.bat的批处理文件,编辑该文件,在第一行后加入set CYGWIN=title ntea,这是因为Cygwin的启动批处理文件需要启动Unix文件系统模拟。修改完毕且保存后退出。


1.5.2 SH链接

运行cygwin,在根目录下输入,cd bin
mv sh.exe sh-original.exe
ln �s bash.exe sh.exe

现在对cygwin的修改搞定

1.6 2.5. 运行

从程序组或者桌面启动Cygwin。

输入:
cd /
ls

能列出目录说明就ok了。

--
由 Pegasus 于 1/14/2008 05:37:00 下午 在 嘻嘻哈哈 上发表

Cygwin使用指南

cygwin是一个在windows平台上运行的unix模拟环境,是cygnus
solutions公司开发的自由软件(该公司开发了很多好东西,著名的还有eCos,不过现已被Redhat收购)。它对于学习unix/linux操
作环境,或者从unix到windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用gnu工具集在windows上进行嵌入式系统开发,非
常有用。随着嵌入式系统开发在国内日渐流行,越来越多的开发者对cygwin产生了兴趣。本文将对其作一介绍。

根据cygwin user guide翻译整理,希望对大家有所帮助。有错误清指出。

1 引言
cygwin
是一个在windows平台上运行的unix模拟环境,是cygnus
solutions公司开发的自由软件(该公司开发了很多好东西,著名的还有eCos,不过现已被Redhat收购)。它对于学习unix/linux操
作环境,或者从unix到windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用gnu工具集在windows上进行嵌入式系统开发,非
常有用。随着嵌入式系统开发在国内日渐流行,越来越多的开发者对cygwin产生了兴趣。本文将对其作一介绍。

2 机理
cygnus
当初首先把gcc,gdb,gas等开发工具进行了改进,使他们能够生成并解释win32的目标文件。然后,他们要把这些工具移植到windows平台上
去。一种方案是基于win32
api对这些工具的源代码进行大幅修改,这样做显然需要大量工作。因此,他们采取了一种不同的方法――他们写了一个共享库(就是cygwin
dll),把win32
api中没有的unix风格的调用(如fork,spawn,signals,select,sockets等)封装在里面,也就是说,他们基于
win32
api写了一个unix系统库的模拟层。这样,只要把这些工具的源代码和这个共享库连接到一起,就可以使用unix主机上的交叉编译器来生成可以在
windows平台上运行的工具集。以这些移植到windows平台上的开发工具为基础,cygnus又逐步把其他的工具(几乎不需要对源代码进行修改,
只需要修改他们的配置脚本)软件移植到windows上来。这样,在windows平台上运行bash和开发工具、用户工具,感觉好像在unix上工作。
关于cygwin实现的更详细描述,请参考http://cygwin.com/cygwin-u...

(cygwin.com在电信ADSL似乎被屏蔽了,不知道原因。)
3 安装设置cygwin
3.1 安装
要安装网络版的cygwin,可以到http://cygwin.com,点击"Install Cygwin Now!"。这样会先下载一个叫做setup.exe的GUI安装程序,用它能下载一个完整的cygwin。按照每一屏的指示可以方便的进行安装。
3.2 环境变量
开始运行bash之前,应该设置一些环境变量。cygwin提供了一个.bat文件,里面已经设置好了最重要的环境变量。通过它来启动bash是最安全的办法。这个.bat文件安装在cygwin所在的根目录下。 可以随意编辑该文件。
CYGWIN变量用来针对cygwin运行时系统进行多种全局设置。开始时,可以不设置CYGWIN或者在执行bash前用类似下面的格式在dos框下把它设为tty
C:\> set CYGWIN=tty notitle glob

PATH
变量被cygwin应用程序作为搜索可知性文件的路径列表。当一个cygwin进程启动时,该变量被从windows格式(e.g.
C:\WinNT\system32;C:\WinNT)转换成unix格式(e.g.,
/WinNT/system32:/WinNT)。如果想在不运行bash的时候也能够使用cygwin工具集,PATH起码应该包含x:\cygwin
\bin,其中x:\cygwin 是你的系统中的cygwin目录。
HOME变量用来指定主目录,推荐在执行bash前定义该变量。当
cygwin进程启动时,该变量也被从windows格式转换成unix格式,例如,作者的机器上HOME的值为C:\(dos命令set
HOME就可以看到他的值,set HOME=XXX可以进行设置),在bash中用echo $HOME看,其值为/cygdrive/c.
TERM变量指定终端型态。如果美对它进行设置,它将自动设为cygwin。
LD_LIBRARY_PATH被cygwin函数dlopen()作为搜索.dll文件的路径列表,该变量也被从windows格式转换成unix格式。多数Cygwin应用程序不使用dlopen,因而不需要该变量。
3.3 改变cygwin的最大存储容量
Cygwin
程序缺省可以分配的内存不超过384
MB(program+data)。多数情况下不需要修改这个限制。然而,如果需要更多实际或虚拟内存,应该修改注册表的
HKEY_LOCAL_MACHINE或HKEY_CURRENT_USER区段。田家一个DWORD键heap_chunk_in_mb并把它的值设为
需要的内存限制,单位是十进制MB。也可以用cygwin中的regtool完成该设置。例子如下:
regtool -i set /HKLM/Software/Cygnus\ Solutions/Cygwin/heap_chunk_in_mb 1024
regtool -v list /HKLM/Software/Cygnus\ Solutions/Cygwin

4 使用cygwin
这一段讲一下cygwin和传统unix系统的不同之处。
4.1 映射路径名
4.1.1 引言
cygwin
同时支持win32和posix风格的路径,路径分隔符可以是正斜杠也可以是反斜杠。还支持UNC路径名。(在网络中,UNC是一种确定文件位置的方法,
使用这种方法用户可以不关心存储设备的物理位置,方便了用户使用。在Windows操作系统,Novell
Netware和其它操作系统中,都已经使用了这种规范以取代本地命名系统。在UNC中,我们不用关心文件在什么盘(或卷)上,不用关心这个盘(或卷)所
在服务器在什么地方。我们只要以下面格式就可以访问文件:
\服务器名\共享名\路径\文件名
共享名有时也被称为文件所在卷或存储设备的逻辑标识,但使用它的目的是让用户不必关心这些卷或存储设备所在的物理位置。)
符合posix标准的操作系统(如linux)没有盘符的概念。所有的绝对路径都以一个斜杠开始,而不是盘符(如c:)。所有的文件系统都是其中的子目录。例如,两个硬盘,其中之一为根,另一个可能是在/disk2路径下。

为许多unix系统上的程序假定存在单一的posix文件系统结构,所以cygwin专门维护了一个针对win32文件系统的内部posix视图,使这些
程序可以在windows下正确运行。在某些必要的情况下,cygwin会使用这种映射来进行win32和posix路径之间的转换。
4.1.2 cygwin mount表
cygwin
中的mount程序用来把win32盘符和网络共享路径映射到cygwin的内部posix目录树。这是与典型unix
mount程序相似的概念。对于那些对unix不熟悉而具有windows背景的的人来说,mount程序和早期的dos命令join非常相似,就是把一
个盘符作为其他路径的子目录。
路径映射信息存放在当前用户的cygwin mount表中,这个mount table
又在windows的注册表中。这样,当该用户下一次登录进来时,这些信息又从注册表中取出。mount
表分为两种,除了每个用户特定的表,还有系统范围的mount表,每个cygwin用户的安装表都继承自系统表。系统表只能由拥有合适权限的用户
(windows nt的管理员)修改。
当前用户的mount表可以在注册表"HKEY_CURRENT_USER/Software/Red Hat, Inc./Cygwin/mounts v" 下看到。系统表
存在HKEY_LOCAL_MACHINE下。
posix
根路径/缺省指向系统分区,但是可以使用mount命令重新指向到windows文件系统中的任何路径。cygwin从win32路径生成posix路径
时,总是使用mount表中最长的前缀。例如如果c:被同时安装在/c和/,cygwin将把C:/foo/bar转换成/c/foo/bar.
如果不加任何参数地调用mount命令,会把Cygwin当前安装点集合全部列出。在下面的例子中,c盘是POSIX根,而d盘被映射到/d。本例中,根是一个系统范围的安装点,它对所有用户都是可见的,而/d仅对当前用户可见。
c:\> mount
f:\cygwin\bin on /usr/bin type system (binmode)
f:\cygwin\lib on /usr/lib type system (binmode)
f:\cygwin on / type system (binmode)
e:\src on /usr/src type system (binmode)
c: on /cygdrive/c type user (binmode,noumount)
e: on /cygdrive/e type user (binmode,noumount)
还可以使用mount命令增加新的安装点,用umount删除安装点。
当Cygwin
不能根据已有的安装点把某个win32路径转化为posix路径时,cygwin会自动把它转化到一个处于缺省posix路径/cygdrive下的的一
个安装点. 例如,如果Cygwin 访问Z:\foo,而Z盘当前不在安装表内,那么Z:\将被自动转化成/cygdrive/Z.
可以给每个安装点赋予特殊的属性。自动安装的分区显示为"auto"安装。安装点还可以选择是"textmode"还是 "binmode",这个属性决定了文本文件和二进制文件是否按同样的方式处理。
4.1.3 其他路径相关信息
cygpath工具提供了在shell脚本中进行win32-posix路径格式转换的能力。
HOME, PATH,和LD_LIBRARY_PATH环境变量会在cygwin进程启动时自动被从Win32格式转换成了POSIX格式(例如,如果存在从该win32路径到posix路径的安装,会把c:\cygwin\bin转为/bin)。

Cygwin介绍

Cygwin是一个用于在Windows上模拟Linux环境的软件。它可以作为那些虚拟机软件的一个部分替代品。之所以将它排在第一个来介绍,是因为它实在给我帮了很大的忙。

运行Cygwin后,你会得到一个类似Linux的Shell环境,在其中你可以使用绝大部分Linux软件和功能。如Gcc,Make,Vim,Emacs等等。总之如果你想使用某个Linux下的功能,而windows上又找不到好的替代品的话,你就可以用Cygwin。我使用的最频繁的是Gcc和Make。我经常用它们来编译一些我从网上下载的开源的工程。这些工程在Windows上编译往往很麻烦。我也用它做过X Server来连接一台真正的Linux服务器,用来测试一个用tcl/tk编写的跨平台的用户界面程序。下面,我逐步介绍Cygwin的基本用法。
使用

安装完成后,在桌面上会有一个Cygwin的图标,双击它,会出现一个windows的命令窗口,过一会,你就会见到熟悉(或者陌生)的 Linux的Shell界面。试一试ls ,是不是可以工作了?

从今往后,你就可以自由的在windows下使用Linux的软件了。基本上你能用到,cygwin都有。如果你要开发可以在两个平台上运行的程序, cygwin也是你前期试验的好地方。从互联网上下载的各种开源代码,也可以在Cygwin里编译,运行,调试。下面介绍一些使用技巧,更多地还要靠大家自己探索拉!

使用Cygwin访问windows的文件
Cygwin安装后,其根目录位于你的安装目录下。所以使用cd /,只能访问到你的安装目录,要访问硬盘上的其他文件,可以使用mount:
mount D:/testdir ~/testdir
这样,你就可以在~/testdir里访问到D:/testdir里的内容了。

使用Cygwin作为X Server
现在的Linux服务器一般都提供X,要从Windows上使用Linux的X,需要在Windows上运行一个X Server。有一些专门为windows开发的软件可以做这个,但是Cygwin自带的X server就可以胜任。下面举例说明如何使用:
首先你必须安装X11包,然后运行Cygwin shell,输入x&。这时候你的桌面上出出现一个布满斜纹大窗口,这就是我们的X server了,回头Linux机器上的X 程序就会显示在这里:

MinGW简介,安装,配置,调试说明

MinGW简介,安装,配置,调试说明
标签: MinGW MinGW-4.1.1.exe Visual-MinGW 0.53 mingw32-make-3.80.0-3.exe

MinGW简介,安装,配置,调试说明

MinGW - Minimalist GNU for Windows
MinGW - Windows平台下GNU工具的最小子集
MinGW: A collection of freely available and freely distributable Windows specific header files and import libraries combined with GNU toolsets that allow one to produce native Windows programs that do not rely on any 3rd-party C runtime DLLs.
MinGW:可以免费获得和发布的Windows头文件和导入库文件,以及可以用来产生不依赖于任何第三方C运行时的GNU工具集。

mingw是windows版本的gnu c/c++工具集 主要包括编译器gcc,连接器make,调试器gdb

MinGW 官方网站为 http://www.mingw.org

可参考最新版本,为如下地址:
http://sourceforge.net/projects/mingw/

安装软件:
1,MinGW-4.1.1.exe,通过网络安装,将所有的东西都装在C:\MinGW(默认目录)
下载地址:http://prdownloads.sourceforge.net/mingw/MinGW-4.1.1.exe?download

2,Visual-MinGW 0.53,安装完毕后,Visual-MinGW会提示让你寻找compile目录,这时候选mingw安装目录(默认是C:\MinGW)即可
下载地址:http://prdownloads.sourceforge.net/visual-mingw/vm-0.53a-20031011.exe?download
3,mingw32-make-3.80.0-3.exe
下载地址:http://prdownloads.sourceforge.net/mingw/mingw32-make-3.80.0-3.exe?download

4,配置环境变量,复制"mingw32-make.exe"增加"make.exe"

5,打开Visual-MinGW,想写点啥就写点啥吧,finish

by Longman 2007.05.10 11:11

提示:
(1)MinGW-4.1.1.exe安装时(这里只是安装"current",不安装"source")下载以下几个包:
ada.tar.gz
binutils.tar.gz
g++.tar.gz
g77.tar.gz
gcc.tar.gz
java.tar.gz
runtime.tar.gz
w32api.tar.gz
objc.tar.gz
mingw32-make.tar.gz

如果你水平可以,完全可以单独下几个自己需要的包配置一下,而不需要安装

在(1)里如上配置为参考网上仁兄的,你也可以默认安装,me too :(

(2)配置环境变量:
PATH C:\MinGW\bin; (千万别直接覆盖PATH变量,务必将其放在最前面,要用分号隔开)
LIBRARY_PATH C:\MinGW\lib
C_INCLUDEDE_PATH C:\MinGW\include
CPLUS_INCLUDE_PATH C: \MinGW\include\c++\3.4.2;C:\MinGW\include\c++\3.4.2\mingw32;C:\MinGW\include \c++\3.4.2\backward;C:\MinGW\include (不同版本的c++版本不同,不要盲目照转,如安装不同的MinGW版本,清注意配置)

(3)将C:\MinGW\bin下的文件"mingw32-make.exe"复制一份并改名为"make.exe",方便以后操作。

测试:

(1)在cmd中执行下make命令(如c:\MinGW\bin>make.exe),如果出现"***No targets specfied and no make file found stop",设置成功。
(2)在cmd中输入"gcc -v",如果屏幕出现"gcc不是内部命令或外部命令,也不是可运行的程序或批处理文件。"表示环境变量设定有问题。如果出现如下显示,表示设定成功。
Reading specs from c:/mingw/bin/../lib/gcc/mingw32/3.4.2/specs
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable
-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --e
nable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-ja
va-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchroniz
ation --enable-libstdcxx-debug
Thread model: win32
gcc version 3.4.2 (mingw-special)

(3)在cmd中输入"mingw32-make -version",如果屏幕出现:
GNU Make 3.80
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
如上显示,恭喜你,MinGW安装成功了

2008年1月11日星期五

GCC

 使用语法:
  gcc [ option filename ]...
    g++ [ option filename ]...
  
  其中 option 为 gcc 使用时的选项(后面会再详述),而 filename 为欲以 gcc 处理的文件
  
  说明:
   这 C 与 C++ 的 compiler 已将产生新程序的相关程序整合起来。产生一个新的程序需要经过四个阶段:预处理、编译、汇编、连结,而这两个编译器都能将输入的文件做不同阶段的处理。虽 然原始程序的扩展名可用来分辨编写原始程序码所用的语言,但不同的compiler,其预设的处理程序却各不相同:
  
  gcc  预设经由预处理过(扩展名为.i)的文件为 C 语言,并於程式连结阶段以 C 的连结方式处理。
  
  g++  预设经由预处理过(扩展名为.i)的文件为 C++ 语言,并於程序连结阶段以 C++ 的连结方式处理。
  
  原始程序码的扩展名指出所用编写程序所用的语言,以及相对应的处理方法:
  
    .c  C 原始程序         ; 预处理、编译、汇编
    .C  C++ 原始程序        ; 预处理、编译、汇编
    .cc C++ 原始程序        ; 预处理、编译、汇编
    .cxx C++ 原始程序        ; 预处理、编译、汇编
    .m  Objective-C 原始程序    ; 预处理、编译、汇编
    .i  已经过预处理之 C 原始程序  ; 编译、汇编
    .ii 已经过预处理之 C++ 原始程序 ; 编译、汇编
    .s  组合语言原始程序      ; 汇编
    .S  组合语言原始程序      ; 预处理、汇编
    .h  预处理文件(标头文件)    ; (不常出现在指令行)
  
  其他扩展名的文件是由连结程序来处理,通常有:
    .o  Object file
    .a  Archive file
  
   除非编译过程出现错误,否则 "连结" 一定是产生一个新程序的最後阶段。然而你也可以以 -c、-s 或 -E 等选项,将整个过程自四个阶段中的其中一个停止。在连结阶段,所有与原始码相对应的.o 文件、程序库、和其他无法自文件名辨明属性的文件(包括不以 .o为扩展名的 object file 以及扩展名为 .a 的 archive file)都会交由连结程序来处理(在指令行将那些文件当作连结程序的参数传给连结程序)。
  
  选项:
  
  不同的选项必须分开来下:例如 `-dr' 这个选项就与 `-d -r' 大不相同。
  
  绝大部份的 `-f' 及 `-W' 选项都有正反两种形式:-fname 及-fno-name (或 -Wname 及 -Wno-name)。以下只列出非预设的那个形式。
  
  以下是所有选项的摘要。以形式来分类。选项的意义将另辟小节说明。
  
  一般性(概略、常用的)选项
         -c -S -E -o file -pipe -v -x language
  
    程序语言选项
         -ansi -fall-virtual -fcond-mismatch
         -fdollars-in-identifiers -fenum-int-equiv
         -fexternal-templates -fno-asm -fno-builtin
         -fno-strict-prototype -fsigned-bitfields
         -fsigned-char -fthis-is-variable
         -funsigned-bitfields -funsigned-char
         -fwritable-strings -traditional -traditional-cpp
         -trigraphs
  
    编译时的警告选项
         -fsyntax-only -pedantic -pedantic-errors -w -W
         -Wall -Waggregate-return -Wcast-align -Wcast-qual
         -Wchar-subscript -Wcomment -Wconversion
         -Wenum-clash -Werror -Wformat -Wid-clash-len
         -Wimplicit -Winline -Wmissing-prototypes
         -Wmissing-declarations -Wnested-externs -Wno-import
         -Wparentheses -Wpointer-arith -Wredundant-decls
         -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch
         -Wtemplate-debugging -Wtraditional -Wtrigraphs
         -Wuninitialized -Wunused -Wwrite-strings
  
    除错选项
         -a -dletters -fpretend-float -g -glevel -gcoff
         -gxcoff -gxcoff+ -gdwarf -gdwarf+ -gstabs -gstabs+
         -ggdb -p -pg -save-temps -print-file-name=library
         -print-libgcc-file-name -print-prog-name=program
  
   最佳化选项
         -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks
         -fdelayed-branch -felide-constrUCtors
         -feXPensive-optimizations -ffast-math -ffloat-store
         -fforce-addr -fforce-mem -finline-functions
         -fkeep-inline-functions -fmemoize-lookups
         -fno-default-inline -fno-defer-pop
         -fno-function-cse -fno-inline -fno-peephole
         -fomit-frame-pointer -frerun-cse-after-loop
         -fschedule-insns -fschedule-insns2
         -fstrength-reduce -fthread-jumps -funroll-all-loops
         -funroll-loops -O -O2
  
    预处理选项
         -Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H
         -idirafter dir -include file -imacros file -iprefix
         file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P
         -Umacro -undef
  
    汇编程序选项
         -Wa,option
    连结程序选项
         -llibrary -nostartfiles -nostdlib -static -shared
         -symbolic -Xlinker option -Wl,option -u symbol
  
    目录选项
         -Bprefix -Idir -I- -Ldir
  
   Target Options
         -b machine -V version
  
   与机器(平台)相关的选项
         M680x0 Options
         -m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881
         -mbitfield -mc68000 -mc68020 -mfpa -mnobitfield
         -mrtd -mshort -msoft-float
  
  VAX Options
         -mg -mgnu -munix
  
  SPARC Options
         -mepilogue -mfpu -mhard-float -mno-fpu
         -mno-epilogue -msoft-float -msparclite -mv8
         -msupersparc -mcypress
  
  Convex Options
         -margcount -mc1 -mc2 -mnoargcount
  
  AMD29K Options
         -m29000 -m29050 -mbw -mdw -mkernel-registers
         -mlarge -mnbw -mnodw -msmall -mstack-check
         -muser-registers
  
  M88K Options
         -m88000 -m88100 -m88110 -mbig-pic
         -mcheck-zero-division -mhandle-large-shift
         -midentify-revision -mno-check-zero-division
         -mno-ocs-debug-info -mno-ocs-frame-position
         -mno-optimize-arg-area -mno-serialize-volatile
         -mno-underscores -mocs-debug-info
         -mocs-frame-position -moptimize-arg-area
         -mserialize-volatile -mshort-data-num -msvr3 -msvr4
         -mtrap-large-shift -muse-div-instruction
         -mversion-03.00 -mwarn-passed-structs
  
    RS6000 Options
         -mfp-in-toc -mno-fop-in-toc
  
  RT Options
         -mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs
         -mfull-fp-blocks -mhc-struct-return -min-line-mul
         -mminimum-fp-blocks -mnohc-struct-return
  
  MIPS Options
         -mcpu=cpu type -mips2 -mips3 -mint64 -mlong64
         -mlonglong128 -mmips-as -mgas -mrnames -mno-rnames
         -mgpopt -mno-gpopt -mstats -mno-stats -mmemcpy
         -mno-memcpy -mno-mips-tfile -mmips-tfile
         -msoft-float -mhard-float -mabicalls -mno-abicalls
         -mhalf-pic -mno-half-pic -G num -nocpp
  
  i386 Options
         -m486 -mno-486 -msoft-float -mno-fp-ret-in-387
  
  HPPA Options
         -mpa-risc-1-0 -mpa-risc-1-1 -mkernel -mshared-libs
         -mno-shared-libs -mlong-calls -mdisable-fpregs
         -mdisable-indexing -mtrailing-colon
  
    i960 Options
         -mcpu-type -mnumerics -msoft-float
         -mleaf-procedures -mno-leaf-procedures -mtail-call
         -mno-tail-call -mcomplex-a

http://blog.csdn.net/visioncat/archive/2006/05/07/711693.aspx

http://blog.vckbase.com/bastet/archive/2005/04/26/4985.aspx
http://www.mingw.org/download.shtml
Best Regards
Miao Jia Hong

2008年1月8日星期二

使用WinSock搜索蓝牙设备

可以利用下面这些变成元素创建一个查询来搜索一定范围内的远程蓝牙设备:

* WSAQUERYSET 结构体
* WSALookupServiceBegin 函数
* WSALookupServiceNext函数
* WSALookupServiceEnd函数

注意 为了使清晰起见,文中忽略了错误处理
搜索并返回远程设备的地址

1. 提供Winsock的版本和实现细节的数据来初始化caller application。可以通过调用WSAStartup函数来获得这个数据。

WSADATA wsd;
WSAStartup (MAKEWORD(1,0), &wsd);

2. 创建并初始化一个WSAQUERYSET变量用于指定搜索参数,设置dwNameSpace成员为NS_BTH限制为查询蓝牙设备。

WSAQUERYSET wsaq;
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;

3. 调用WSALookupServiceBegin函数来执行一个查询。

int iRet = WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup);
将LUP_CONTAINERS赋给dwFlags参数,启动SDP来搜索蓝牙设备。
注意 将dwFlags参数设为零将执行一个服务搜索。
WSALookupServiceBegin函数返回一个句柄到hLookup参数中。

4. 要枚举在上一步中调用WSALookupServiceBegin所找到的设备,就要使用WSALookupServiceNex函数。函数返回一个指向存有查询结果的WSAQUERYSET及构体。
1. 设置一个WSAQUERYSET结构体来储存WSALookupServiceNext函数返回的设备数据。

CHAR buf[4096];
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob = NULL;

2. 调用WSALookupServiceNext并将WSALookupServiceBegin返回的hLookUp参数传递给它。为了提高性能,对WSALookupServiceBegin 的调用只返回设备的地址并存储在内存中。要返回设备的名称和地址,就要将LUP_RETURN_NAME | LUP_RETURN_ADDR赋给dwFlags参数。

DWORD dwSize = sizeof(buf);
int iRet = WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults)
可以通过循环调用WSALookupServiceNext来枚举所有的设备。

5. 调用WSALookupServiceEnd函数来结束设备搜索。这个函数将释放由WSALookupServiceBegin创建的lookup句柄。

WSALookupServiceEnd(hLookup);

6. 要结束对Winsock服务的使用,调用WSACleanup函数。在程序中对每个成功调用的WSAStartup都必须对应地调用WSACleanup。

error LNK2001错误

在我的程序中,碰到如下错误:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
我的解决方法如下:
点击"Project|settings",选择C/C++标签,在CODE GENERATION分类中选择"Debug MultiThreaded"
再重新rebuild all后,问题可以得到解决.
可能原因是我在程序中用到
HINSTANCE hInstance = GetModuleHandle(NULL);
DialogBoxParam(hInstance, (LPCTSTR)IDD_QQTDlg, 0, (DLGPROC)QQDlg, 0);
这个是需要多线程的,因此会出现上面的问题。
经网上查阅资料,得到此类问题的常用解决办法。如下:
在创建MFC项目时, 不使用MFC AppWizard向导, 如果没有设置好项目参数, 就会在编译时产生很多连接错误, 如error LNK2001错误, 典型的错误提示有:
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
下面介绍解决的方法:
1. Windows子系统设置错误, 提示:
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Windows项目要使用Windows子系统, 而不是Console, 可以这样设置:
[Project] --> [Settings] --> 选择"Link"属性页,
在Project Options中将/subsystem:console改成/subsystem:windows
2. Console子系统设置错误, 提示:
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16控制台项目要使用Console子系统, 而不是Windows, 设置:
[Project] --> [Settings] --> 选择"Link"属性页,
在Project Options中将/subsystem:windows改成/subsystem:console
3. 程序入口设置错误, 提示:
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
通常, MFC项目的程序入口函数是WinMain, 如果编译项目的Unicode版本, 程序入口必须改为wWinMainCRTStartup, 所以需要重新设置程序入口:
[Project] --> [Settings] --> 选择"C/C++"属性页,
在Category中选择Output,
再在Entry-point symbol中填入wWinMainCRTStartup, 即可
4. 线程运行时库设置错误, 提示:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
这是因为MFC要使用多线程时库, 需要更改设置:
[Project] --> [Settings] --> 选择"C/C++"属性页,
在Category中选择Code Generation,
再在Use run-time library中选择Debug Multithreaded或者multithreaded
其中,
Single-Threaded 单线程静态链接库(release版本)
Multithreaded 多线程静态链接库(release版本)
multithreaded DLL 多线程动态链接库(release版本)
Debug Single-Threaded 单线程静态链接库(debug版本)
Debug Multithreaded 多线程静态链接库(debug版本)
Debug Multithreaded DLL 多线程动态链接库(debug版本)
单线程: 不需要多线程调用时, 多用在DOS环境下
多线程: 可以并发运行
静态库: 直接将库与程序Link, 可以脱离MFC库运行
动态库: 需要相应的DLL动态库, 程序才能运行
release版本: 正式发布时使用
debug版本: 调试阶段使用

2008年1月7日星期一

手工编辑.inf文件 破解 WIDCOMM 蓝牙驱动的方法

对于使用 WidcommLicensePatcher 1.8 破解license 文件仍然无法找到蓝牙适配器的可以用以下方法完成破解 (转自魔蝎,并进行了局部修改)

widcomm 经过修改安装inf文件和lisence文件,达到了破解的目的,支持32位及64位操作系统,支持多种usb蓝牙设备,如下:
%ABOCOMDFU.DeviceDesc%=DFUBTUSB, USBVID_07B8&PID_B02D
%ABOCOMDFU.DeviceDesc%=DFUBTUSB, USBVID_07B8&PID_B02E
%ABOCOM.DeviceDesc%=SUSPENDUSB, USBVID_07B8&PID_B02C
%BRCMANYCOMUHE.DeviceDesc%=BRSMARTUSB, USBVID_0A5C&PID_2111
%BRCMANYCOM.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_2102
%ABOCOM.DeviceDesc%=SUSPENDUSB, USBVID_07B8&PID_B02B
%FORMOSA4.DeviceDesc%=SUSPENDUSB, USBVID_2001&PID_F118
%FORMOSA3.DeviceDesc%=SUSPENDUSB, USBVID_2001&PID_F117
%FORMOSA2.DeviceDesc%=SUSPENDUSB, USBVID_2001&PID_F116
%FORMOSA1.DeviceDesc%=SUSPENDUSB, USBVID_2001&PID_F111
%KENSINGTONEDR.DeviceDesc%=BRSMARTUSB, USBVID_047D&PID_105E
%BARCODA.DeviceDesc%=SUSPENDUSB, USBVID_174B&PID_0001
%SITECOM.DeviceDesc%=SUSPENDUSB, USBVID_3574&PID_21F6
%SITECOM.DeviceDesc%=SUSPENDUSB, USBVID_3574&PID_21F4
%LINKSYS.DeviceDesc%=SUSPENDUSB, USBVID_13B1&PID_0019
%ALPS.DeviceDesc%=BTWUSB, USBVID_044e&PID_3001 ; ALPS based VID&PID
%COMPAQ.DeviceDesc%=BTWUSB, USBVID_049F&PID_0027 ; COMPAQ CSR based VID&PID
%IBM.DeviceDesc%=BTWUSB, USBVID_04BF&PID_030A ; IBM CSR based VID&PID
%TDK.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0309 ; TDK CSR based VID&PID
%IBMBDC.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0310 ; IBM BDC CSR based VID&PID
%TDK.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0319 ; TDK USB ADAPTER
%TDK.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0320 ; TDK CSR BC2 based VID&PID
%IBM.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0317 ; ULTRAPORT
%IBMBDC.DeviceDesc%=BTWUSB, USBVID_04BF&PID_0318 ; BDC
%ERICMN.DeviceDesc%=BTWUSB, USBVID_0BDB&PID_1000 ; Ericsson Business Mobile Networks BV VID&PID
%ERICMP.DeviceDesc%=BTWUSB, USBVID_0BDB&PID_1002 ; Ericsson Multipoint VID&PID
%CSR.DeviceDesc%=BTWUSB, USBVID_0A12&PID_0001 ; CSR VID&PID
%ERICSSONUSB.DeviceDesc%=BTWUSB, USBVID_08EA&PID_ABBA ; Ericsson VID&PID
%BROADCOM.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_200A ; Broadcom VID&PID
%BROADCOM.DeviceDesc%=BRSMARTUSB, USBVID_0A5C&PID_2009 ; Broadcom VID&PID Smart dongle
%BROADIBM.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_201E ; Broadcom-IBM VID&PID Smart dongle
%BROADCOM.DeviceDesc%=BRSMARTUSB, USBVID_0A5C&PID_2020 ; Broadcom VID&PID Unified UHE
%BROADCOM.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_2045 ; Broadcom 2045 VID&PID
%BROADIBMEDR.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_2110 ; Broadcom IBM VID&PID
%BRCM2045UHE.DeviceDesc%=BRSMARTUSB, USBVID_0A5C&PID_2100 ; Broadcom 2045 VID&PID, UHE
%BRCM2045.DeviceDesc%=SUSPENDUSB, USBVID_0A5C&PID_2101 ; Broadcom 2045 VID&PID, non UHE
%SAMSUNG.DeviceDesc%=BTWUSB, USBVID_055D&PID_0BB1 ; SAMSUNG BC02 external
%SIWAVE.DeviceDesc%=BTWUSB, USBVID_0C10&PID_0000 ; Silicon Wave VID&PID
%SIWAVE.DeviceDesc%=BTWUSB, USBVID_05B1&PID_1389 ; Silicon Wave VID&PID
%ZEEVO.DeviceDesc%=BTWUSB, USBVID_0B7A&PID_07D0 ; Zeevo VID&PID
%DELL.DeviceDesc%=SUSPENDUSB, USBVID_413C&PID_8000 ; Dell BC02 VID&PID
%IBMBM.DeviceDesc%=BTWUSB, USBVID_1668&PID_0441 ; IBM integrated BT Modem VID&PID
%IBMBM3.DeviceDesc%=SUSPENDUSB, USBVID_1668&PID_2441 ; IBM Integrated Bluetooth III VID&PID
%MICROTUNE.DeviceDesc%=BTWUSB, USBVID_0F4D&PID_1000 ; Microtune USB Bluetooth Device VID&PID
%MSI.DeviceDesc%=BTWUSB, USBVID_0DB0&PID_1967 ; MSI USB Device VID&PID
%MSI.DeviceDesc%=BTWUSB, USBVID_0DB0&PID_6970 ; MSI USB Device VID&PID
%MSI.DeviceDesc%=BTWUSB, USBVID_0DB0&PID_697A ; MSI USB Device VID&PID
%MSI.DeviceDesc%=BTWUSB, USBVID_0DB0&PID_6855 ; MSI USB Device VID&PID
%MSFT.DeviceDesc%=BTWUSB, USBVID_045E&PID_007E ; Microsoft
%NSCEVAL.DeviceDesc%=BTWUSB, USBVID_0400&PID_0807 ; National Semi Bluetooth board
%STM.DeviceDesc%=WDSMARTUSB, USBVID_0483&PID_5000 ; STM VID&PID
%TI.DeviceDesc%=WDSMARTUSB, USBVID_0451&PID_1234 ; TI VID&PID
%TI.DeviceDesc%=BTWUSB, USBVID_0451&PID_ffff ; TI VID&PID
%SONY.DeviceDesc%=BTWUSB, USBVID_044e&PID_2014 ; SONY VID&PID
%FORMOSA.DeviceDesc%=BTWUSB, USBVID_0D9A&PID_0001 ; FORMOSA VID&PID
%FORMOSA.DeviceDesc%=BTWUSB, USBVID_4851&PID_1103 ; FORMOSA VID&PID
%BLUETHUMB.DeviceDesc%=SUSP1USB, USBVID_049F&PID_0086 ; BLUETHUMB USB Device VID&PID
%LOGITECH.DeviceDesc%=BTWUSB, USBVID_046D&PID_C707 ; LOGITECH VID&PID
%LOGITECH.DeviceDesc%=BTWUSB, USBVID_046D&PID_C708 ; LOGITECH VID&PID
%LOGITECH.DeviceDesc%=BTWUSB, USBVID_046D&PID_C709 ; LOGITECH VID&PID
%LOGITECH.DeviceDesc%=BTWUSB, USBVID_046D&PID_C70D ; LOGITECH VID&PID
%GIANT.DeviceDesc%=BTWUSB, USBVID_0FD1&PID_0001 ; Giant VID&PID
%BELKIN.DeviceDesc%=SUSPENDUSB, USBVID_050D&PID_0083
%PANASONIC.DeviceDesc%=BTWUSB, USBVID_04AD&PID_2501 ; Panasoic VId&PID
%ICSI.DeviceDesc%=BTWUSB, USBVID_0547&PID_0001 ; ICSI USB Device VID&PID
%PHILIPS.DeviceDesc%=BTWUSB, USBVID_0471&PID_0809 ; Philips BluePearl VID&PID
%ITRONIX.DeviceDesc%=BTWUSB, USBVID_11D9&PID_2600 ; Itronix Bluetooth Device VId&PID
%DELLELWOOD.DeviceDesc%=BRSMARTUSB, USBVID_413C&PID_8501 ; Dell Elwood VId&PID
%BROADCOMHP.DeviceDesc%=SUSP1USB, USBVID_03F0&PID_011D ; BROADCOM VId&PID for Hp
%BROADCOM2045HP.DeviceDesc%=SUSP1USB, USBVID_03F0&PID_171D ; BROADCOM VId&PID for Hp
%BRCMHPPRINT.DeviceDesc%=SUSPENDUSB, USBVID_03F0&PID_D104 ; BROADCOM VId&PID for Hp
%BCHPTransceiver.DeviceDesc%=BRSMARTUSB, USBVID_03F0&PID_0624 ; BROADCOM VId&PID for Hp
%ISSC.DeviceDesc%=BTWUSB, USBVID_1131&PID_1001 ; ISSC USB Device Vid&PID
%AIR2U.DeviceDesc%=BTWUSB, USBVID_1310&PID_0001 ; Air2U Device Vid&Pid
%AIR2UBRCM.DeviceDesc%=SUSPENDUSB, USBVID_1310&PID_0002 ; Air2U(BCM) Device Vid&Pid
%FCS.DeviceDesc%=BTWUSB, USBVID_0BF8&PID_1003 ; Fujitsu Siemens Vid&Pid
%ACTIONTEC.DeviceDesc%=BTWUSB, USBVID_1668&PID_0500 ; Actiontec USB Bluetooth Device BTM200
%TAIYOYUDEN.DeviceDesc%=BTWUSB, USBVID_0C24&PID_0001 ; TAIYO YUDEN USB Device VID&PID
%TAIYOYUDEN2.DeviceDesc%=BTWUSB, USBVID_0C24&PID_0002 ; TAIYO YUDEN USB Device VID&PID
%SAMSUNGTY.DeviceDesc%=BTWUSB, USBVID_04E8&PID_7021 ; Samsung TY USB Device VID&PID
%MICROLINK.DeviceDesc%=BTWUSB, USBVID_148D&PID_2430 ; MICROLINK USB Device VID&PID
%DELLU2.DeviceDesc%=SUSPENDUSB, USBVID_413C&PID_8103 ; DELLCSR's U2 module VID&PID
%DELLPHISH.DeviceDesc%=SUSPENDUSB, USBVID_413C&PID_8110 ; DELL PHISH module VID&PID
%TECOM.DeviceDesc%=SUSPENDUSB, USBVID_041E&PID_5015 ; TECOM USB PID&VID
%KENSINGTON.DeviceDesc%=BRSMARTUSB, USBVID_047D&PID_105D ; Kensington USB PID&VID
%TECOM.DeviceDesc%=BRSMARTUSB, USBVID_0D62&PID_2026 ; TECOM Darfon USB PID&VID
%BRCMMOTO.DeviceDesc%=SUSPENDUSB, USBVID_22B8&PID_0850

在这儿顺便普及一下windows对usb设备的识别,windows将通过VID及PID来识别usb设备。
VID指Vendor ID(厂家ID);PID指Product ID(产品ID);
因此只要在安装文件btwusb.inf里面列明所有的VID和PID,理论上就支持全部的蓝牙适配器,上面就是这个版本的安装脚本,你可以找你的蓝牙适配器是否在里面,比方说我的是ISSC的芯片,就在:
%ISSC.DeviceDesc%=BTWUSB, USBVID_1131&PID_1001 ; ISSC USB Device Vid&PID
这儿指明了。

如果此安装脚本里面没有你的蓝牙适配器,你仅仅需要在btwusb.inf文件里面加入你的VID和PID就可以了,照着上面的格式。

下一个问题,怎么知道我的usb dongle的VID和PID呢?很简单,你还没装驱动时:
在桌面上右键单击我的电脑->属性->硬件->设备管理器->蓝牙设备 下面会有一个未知设备->双击查看属性->详细信息->在下拉框选 设备范例ID->下面会显示大概如下:
USBVID_1131&PID_1001&2593D763&0&1
的字串,其中的VID_1131&PID_1001就是你usb dongle的VID和PID了。

蓝牙技术-设备查询及服务发现

正如标题所示,设备查询及服务发现是使用蓝牙技术的第一步工作,只有这步工作能够处理好,才可以接下来使用Bluetooth(蓝牙) for Windows DK API中其他的类,从而实现我们需要完成的功能,传输文件、语音发送、fax...

运行实现环境:Windows 2000 sp4 Bluetooth for Windows DK API Reference Guide(WIDCOMM) VC++6.0英文版

首先介绍开发蓝牙工程所在环境的一些必要设置:
确认安装了提供Bluetooth开发的相应SDK,本例是Bluetooth for Windows DK API Reference Guide,WIDCOMM公司提供的,版本1.4.2.10
(接下来的设置因sdk的不同而不同,本例设置可以参照上述dk的帮助说明有关Implementation部分)
接着介绍几个关键的类:
CBtIf 提供接口级函数,请求及服务发现使用该类
CSdpService管理sdp服务记录
CSdpDiscoveryRec获取sdp发现记录并提供查询方式

---------------------------------
由于蓝牙技术的实现类似socket,必须有服务器端及客户端部分。有所不同的是蓝牙的服务器一般来说可以支持多个客户端,而不像p2p中只能有一个。
服务器端和客户端都可以作为连接的发起者,因此作为设备查询和服务发现来说,服务器端和客户端的实现完全一致,所不同的是服务器端必须有相应的服务提供,而客户端则可以没有任何服务支持。因本文的重点放在如何实现设备查询及服务发现,因此暂不考虑如何在服务器端添加相应服务(具体实现是通过上述 CSdpService、CSdpDiscoveryRec)下面就来讲述sdp的具体实现。

具体来说实现主要都是通过类CBtIf完成的,下面有相应过程的简要分析:

首先,必须从CBtIf继承相应类的对象,这一步必须完成,否则无法使用sdk中的函数。
具体函数调用关系如下:
Client Server
CBtIf::StartInquiry()---------------------------------->
CBtIf::OnDeviceResponded()<-------------------------------
.
.
CBtIf::OnDeviceResponded()<-------------------------------
CBtIf::OnInquiryComplete()<--------------------------------- 设备查询阶段

CBtIf::StartDiscovery(address)---------------------->
CBtIf::OnDiscoveryComplete()<------------------------------ 服务发现阶段

CBtIf::ReadDiscoveryRecords()

上述的调用关系比较明确,有几点需要说明,首先提出任务可以从客户端发起,同样服务器端也可以发起,上图是客户端发起。
一方调用StartInquiry()函数后,一旦有设备回应,则OnDeviceResponded()函数就被唤起。值得注意的是这个回应可以是同一设备多次回应,也可以是不同设备的不同回应。(主要因为同一设备名字和其他属性都可以作为不同独立的回应)需要你在该函数中加入相应处理。
等OnInquiryComplete()函数被调用,表示设备查找完成,意味着可以进行服务发现。
然后可以调用StartDiscovery(),这个函数调用时必须附带一具体设备的地址,这个地址在上面的设备查询过程中可以得到。
另外最后一点就是当服务发现完成后,得到数据的一方是通过调用ReadDiscoveryRecords()函数来读取具体的服务内容。
(上述函数都有相应的参数,这里省略,具体可以查询相应sdk)
下面给一段具体代码,便于大家理解上述过程。
---------------------------------
void CBTDlg::OnSearch()
{
// TODO: Add your control notification handler code here
if (!StartInquiry()) //调用
SetDlgItemText(IDC_STATUS_TEXT,"ERROR--Unable to start device inquiry!");
}

void CBTDlg::OnDeviceResponded (BD_ADDR bda, DEV_CLASS devClass, BD_NAME bdName, BOOL bConnected) //对回应进行相应处理
{

// Add the device address and name (if any)
// to the Server List. It is OK to pass
// duplicates. This method will ignore them.
CString item_text;
int item_count = m_ServerList.GetItemCount(); //listview control

for(int x=0;x<item_count;x++)
{
CBdInfo* p_CmpInfo = (CBdInfo*)m_ServerList.GetItemData(x);
if (p_CmpInfo->isBdAddrEqual(bda))
{
if (p_CmpInfo->m_Name.GetLength() == 0)
{
p_CmpInfo->m_Name = bdName;
m_ServerList.SetItemText(x,0,p_CmpInfo->DeviceAsString());
}
return;
}
}
CBdInfo* p_Info = new CBdInfo(bda,bdName);

m_ServerList.InsertItem(item_count,p_Info->DeviceAsString());
m_ServerList.SetItemData(item_count,(LPARAM)p_Info);

}

void CBTDlg::OnDiscovery()
{
// TODO: Add your control notification handler code here
StopInquiry();
//通过新线程完成服务发现
m_pDiscoveryThread = AfxBeginThread(CBTDlg::DiscoverServices,this);
}

UINT CBTDlg::DiscoverServices(LPVOID pParam)
{
CBTDlg* p_Dlg = static_cast<CBTDlg*>(pParam);
CString strServiceName = "";
POSITION pos = p_Dlg->m_ServerList.GetFirstSelectedItemPosition();
if (pos!=NULL)
{
int nItem = p_Dlg->m_ServerList.GetNextSelectedItem(pos);
CBdInfo* p_Info = (CBdInfo*)p_Dlg->m_ServerList.GetItemData(nItem);

p_Dlg->SetDlgItemText(IDC_STATUS_TEXT,"Please Waiting for Services discovering...:"+p_Info->DeviceAsString());

if (!p_Dlg->StartDiscovery(p_Info->m_BdAddr,NULL)) //开始服务发现
{
p_Dlg->SetDlgItemText(IDC_STATUS_TEXT,"Discovery Failed!"+p_Info->DeviceAsString());
}
else
{
WaitForSingleObject(p_Dlg->m_hEventStopDiscoveryThread,30000);//等待完成到达

p_Dlg->SetDlgItemText(IDC_STATUS_TEXT,"Services on : "+p_Info->DeviceAsString());
p_Dlg->m_ServerList.DeleteAllItems();
p_Dlg->m_ServerList.DeleteColumn(0);
p_Dlg->m_ServerList.InsertColumn(0,"Service",LVCFMT_CENTER,180);

if (!p_Dlg->m_bDialogClosed)
{
CSdpDiscoveryRec sdp_Record[MAX_SERVICE];
int nServiceNumber = 0;
nServiceNumber = p_Dlg->ReadDiscoveryRecords(p_Info- >m_BdAddr,MAX_SERVICE,sdp_Record); //读取具体服务内容

if (nServiceNumber != 0)
{
for(int i=0;i<nServiceNumber;i++)
{
strServiceName = sdp_Record[i].m_service_name;
p_Dlg->m_ServerList.InsertItem(i,strServiceName);
}
}
else
p_Dlg->m_ServerList.InsertItem(0,"None!");

p_Dlg->m_ServerList.EnableWindow(FALSE);
}
else
SetEvent(p_Dlg->m_hEventKillDiscoveryThread);
}
}
p_Dlg->m_pDiscoveryThread = NULL;
return 0;
}

通过上面的介绍,只有掌握了蓝牙技术如何实现设备查询及服务发现后,才可以正确确认对方是否提供有相应的服务内容,从而为下一步使用其他传输或通讯技术打下基础。