Using the Library: InTheHand. in VS2008 C++

Topics: Bluetooth - Microsoft
Jul 5, 2012 at 4:52 PM

Hi this project looks great

I'm trying to get a BT Serial socket setup in a program written in C++ in VS2008 Express. I've been able to import the library in to the environment and compile/link the Library. However when I actually go to add some of the library methods and members, nothing is recognised. I cant get the intellisense to work on my using namespace directives. 

Should the intellisense work?

Should these libraries work in my environment?

Do I need to recompile the library in VS2008 Express?

Jul 6, 2012 at 12:12 AM

Disregard, I was able to get the library working with no modification. I think the key issue was that I was implementing a class contained in a c++ header file named Bluetooth.h. I figured that it may have of overloaded a couple of other header files with the same name. Once I changed it to something else it worked.

so Intellisense and the libraries work, and I didn't need ot recompile the library in VS2008 Express

cheers

Pete

Oct 1, 2012 at 11:04 AM

Just some more detail around this...

I had to write a new class to wrap the managed C# code so that it could be used in a C++ program... why? I'm sure someone at MS could enlighten why some libraries cant be integrated directly as per normal header files. Anyhow,

to do this the managed library should be incorporated in to the new class using

gcroot<> defined in vcclr.h, in order to essentially create usable instances of the classes listed by the library. There are a couple of documents on the net to show how to use gcroot<> in the header file to declare the instance you want to use, but you must use gcnew to initialize that instance.An example from both files is below:

BTHandler.h:

#pragma once
#using <c:\Program Files\32Feet.NET\Net\InTheHand.Net.Personal.dll>
#using <System.dll>

#include <vcclr.h>
#include <iostream>

using namespace std;
using namespace InTheHand::Net; // e.g. BluetoothAddress, BluetoothEndPoint etc
using namespace InTheHand::Net::Sockets; // e.g. BluetoothDeviceInfo, BluetoothClient, BluetoothListener
using namespace InTheHand::Net::Bluetooth; // e.g. BluetoothService, BluetoothRadio
using namespace System;//Guid
using namespace System::Net::Sockets;//NetworkStream


//using namespace System::Runtime::InteropServices::GCHandle; // gcroot
//using namespace std;

class BTHandler
{
public:
    Guid SerialPortUUID;
   
    gcroot<BluetoothClient^> BTClient ;
    gcroot<BluetoothAddress^> BTAddress;
    gcroot<BluetoothListener^> BTListener;
    gcroot<BluetoothEndPoint^> BTEndPoint;
    gcroot<BluetoothService^> BTService;
   
    gcroot<cli::array<BluetoothDeviceInfo^,1>^> Peers;

    gcroot<NetworkStream^> PeerStream;
   
    gcroot<cli::array<unsigned char,1>^> ReadArray;
    gcroot<cli::array<unsigned char,1>^> WriteArray;

....

 

and from BTHandler.cpp

#include "BTHandler.h"
//#include "IBTHandler.h"


BTHandler::BTHandler(void)
{
  state = NONE;
  SerialPortUUID = BTService->SerialPort;

 
  BTClient = gcnew BluetoothClient();
  messageCode = WAIT_FOR_REPLY;
 
}

BTHandler::~BTHandler(void)
{
    BTClient->Close();
   
    /* BTClient;
    delete BTListener;
    delete BTEndPoint;
    delete BTService;
    delete BTAddress;
    delete Peers;
    delete PeerStream;*/
}

void BTHandler::Discover (void)
{    //Peers = gcnew BluetoothDeviceInfo(
   
    //TargetAddress = gcnew cli::array<unsigned char^, 6>;
    //TargetAddress->
   
    BTClient->DiscoverDevices(5, false, false, true)->CopyTo(Peers,0);
    for (int i = 0 ; i < Peers->Length; i++)
    {
        if (Peers[i]->DeviceAddress->ToString("C") == "5C:FF:35:32:D4:4D")
        {
            BTAddress = gcnew BluetoothAddress(Peers[i]->DeviceAddress->ToInt64());
            break;
        }
    }
   
    BTEndPoint = gcnew BluetoothEndPoint(BTAddress, SerialPortUUID);
    //SelectBTDeviceDialog= gcnew SelectBluetoothDeviceDialog();
   
}

//This is the default. It will listen for incomming connections on the SS
void BTHandler::Listen(void)
{

    BTListener = gcnew BluetoothListener(SerialPortUUID);
    BTListener->Start(1);
    SetState(LISTENING);

    //while (1)
    //{
    //    cout<<"Listening..."<<endl;
    //    if (BTListener->Pending())
    //    {
                   
    //        Connect(2);
    //        return;
    //    }
    //}
}

// This must be called after Discover when the user has a valid Endpoint held in BTEndPoint
void BTHandler::Connect(int type)
{

    if (type == 1) //connect to a discovered Endpoint
    {
        SetState(CONNECTING);
        BTClient->Connect(BTEndPoint);

       
            PeerStream=BTClient->GetStream();


       
    }
    else if (type == 2)
    {
        SetState(CONNECTING);
       
        BTClient = BTListener->AcceptBluetoothClient();
       
        if (BTClient->Connected)
        {
            SetState(CONNECTED);
            PeerStream = BTClient->GetStream();
            if (!PeerStream->CanRead)
            {
                cout<<"PeerStream is not readable"<<endl;

            }
        }
        else if (!BTClient->Connected)
        {
            SetState(NONE);
            cout<< "Connection Failed"<<endl;
        }
    }
   
}

Additionally the UUID defines the type of device you are connecting with. It needs to be specified in addition to the MAC address for the device.  There are a number of UUIDs that already defined as part of the Bluetooth Standard but you can generate your own. In my case I used the predefined Serial Port UUID. If you are using a device from a specific manufacturer you will need to know the UUID otherwise you will not be able to connnect with it.

I am using the BT libraries in a slave device so I dont actually activate the discover button but use the Listen function to check incomming connections and connect to them.

Overall the difficulty of using managed code in the native code was overcome but its existance and double handling with gcroot should be unnecessary. If you aren't tied to a OS, then consider using Android or another Linux OS, code seems easier to implement and android has excellent Human Machine Interfaces.

Cheers

Peter