- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
基于Windows CE.NET实现蓝牙通讯模块的几种方法
利用P/Invoke方法编写蓝牙通讯模块,DllI-port属性非常有用。下面的代码将用例子说明此通用方案,例中托管程序将调用MessageBox(位于User32.lib中):
using
using namespace System:: Runtime::InteropSer-vices;
namespace SysWin32
{
[DllImport ( "user32. dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(void * hWnd, wchar_t * lpText,wchar_t * lpCaption, unsigned int uType);
}
int main()
SysWin32 :: MessageBox(0, L" Hello world ! ", L"Greetings", 0)
}
注意包含DllImport的代码行。此代码行根据参数值通知编译器,使之声明位于User32.dll中的函数,并将签名中出现的所有字符串(如参数或 返回值)视为Unicode字符串。如果缺少EntryPoint参数,则默认值为函数名。另外,由于CharSet参数指定Unicode,因此公共语 言运行库将首先查找称为MessageBoxW的函数。如果运行库未找到此函数,它将根据调用约定查找MessageBox以及相应的修饰名。
当调用用户定义的DLL中所包含的函数时,有必要将extern"C"添加在DLL函数声明之前,如下所示:extern"C"SAMPLEDLL_API int fnSam-pleDLL(void);
在调用非本机码时,需要注意的是要将非结构化参数由托管封送处理为本机码形式。可以利用CharSet参数值的作用,将参数中字符串(string*类 型)都自动转换为wchar_t*。同样,所有Int32参数类型转换为非托管int,UInt32参数类型转换为非托管unsignedint,而 Intl6参数类型转换为了short int。char*用于[in]参数的为String*(CharSet=Ansi),用于[out]参数或返回 值的为Text::StringBuilder*。wchar-t*用于[in]参数为String*(CharSet=Unicode),用于 [out]参数或返回值的为Text::StringBuilder*。需要注意的是函数指针必须具有_stdcall调用约定,这是因为这是 DllImport支持的唯一类型。对于数组来说数组(如wchar_t*[ ]),CharSet参数仅应用于函数参数的根类型。因此,无论 CharSet的值是什么,String*_ _gc[ ]将被封送处理为wchar_t*[]。除简单类型外,运行库还提供了一种机制,可以将简单结构 由托管上下文封送处理为非托管上下文。简单结构不包含任何内部数据成员指针、结构化类型的成员或其他元素。
在做一个关于蓝牙通讯程序前,还需要一些关于蓝牙的基础知识。一个蓝牙模块程序需要包含开启蓝牙,配对,连接,建立串行通道,然后开启通讯过程,还需要在 应用程序中设置串行端口。因为蓝牙技术有安全方面的设置,所以需要对蓝牙设备进行配对。蓝牙的工作状态总共有3种,分别为开启、关闭、可发现。并且所有的 通讯设备都必须有一个对应的DeviceID,蓝牙也不例外,蓝牙的DeviceID是一串以":"分隔的16进制的数字。有了上述知识,就可以在托管码中利用P/Invoke方法开始编写蓝牙通讯模块了。
对应的每一步需要调用的基本函数如下:
•获取本地设备的ID
[DllImport ( "Btdrt. dll", SetLastError = true) ]
public static extern int BthReadLocalAddr (byte[]PBa)
•获取远程设备的ID
[DllImport( "ws2. dll", EntryPoint = "WSALook-upServiceBegin", SetLastError= true)]
public static extern int CeLookupServiceBegin(byte[ ] pQuerySet, LookupFlags dwFlags, ref intlphLookup)
•监听服务
[DllImport (" ws2. dll", EntryPoint = "WSASetSer-vice", SetLastError= true)]
public static extern int CeSetService
(byte[ ] pQuerySet, RNRSERVICE_REGISTER,LookupFlags dwFlags)
•连接
[DllImport ( "mscoree", EntryPoint = "@ 339" )]
public static extern int connect (int s, byte []name, int namelen)
•蓝牙的安全设置
获取配对码请求
[DllImport("Btdrt. dll", SetLastError= true)]
public static extern int BthGetPINRequest(byte[]pba)
设置配对码
[DllImport( "btdrt. dll", SetLastError= true)
public static extern int BthSetPIN(byte[] pba, intcPinLength, byte [] ppin)
创建ACL连接:
[DllImport("Btdrt. dll", SetLastError= true)
public static extern int BthCreateACLConnection (byte[] pbt, ref ushort phandle);
然后是配对码验证:
[DllImport("Btdrt. dll", SetLastError= true)]
public static extern int BthAuthenticate (byte []pbt);
然后一定要关闭连接:
[DllImport("Btdrt. dll", SetLastError= true)]
public static extern int BthCloseConnection(ushorthandle);
•设置蓝牙无线电状态
[DllImport("BthUtil. dll", SetLastError= true)]public static extern int BthSetMode (RadioModedwMode)
在建立好蓝牙设备的连接后,就可以进行两个蓝牙设备之间的通讯了。由于可以将蓝牙通信当作一个虚拟的串行通信来处理,所以在建立通讯的过程中可以采用类似于串口之间的通讯方式。而关于串口通讯这方面资料很多,本文就不具体详述了。
1.2 利用微软蓝牙嵌入式工具包编写蓝牙通讯模块
微软蓝牙嵌入式工具包是微软公司新推出来基于.NET Compact Framework 2.0的一款专门用来快速开发蓝牙应用程序的工具包,直接 在.NET平台下直接调用其中类库,可以快速,简单的开发一般的蓝牙应用程序。不过该工具包只能在Windows CE 5.0下使用。利用工具包可以完 成:启动一个蓝牙服务,寻找周边蓝牙设备,连接已存在的蓝牙设备或者服务。工具包可以在微软网站下载。
来源:中国传动网