Hi Nicholas,
I finished a couple of more calls to APIs but got struck with this one. I
feel I'm again erring on some structure conversion. Could you please take a
look at the code and advise?
/*
typedef ULONGLONG BTH_ADDR;
typedef struct _BLUETOOTH_ADDRESS {
union {
BTH_ADDR ullLong; // easier to compare again BLUETOOTH_NULL_ADDRESS
BYTE rgBytes[ 6 ]; // easier to format when broken out
};
} BLUETOOTH_ADDRESS_STRUCT;
#define BLUETOOTH_ADDRESS BLUETOOTH_ADDRESS_STRUCT
#define BLUETOOTH_NULL_ADDRESS ( (ULONGLONG) 0x0 )
*/
[StructLayout(LayoutKind.Explicit)]
internal class BluetoothAddress
{
[MarshalAs(UnmanagedType.U8)]
[FieldOffset(0)] internal ulong ullLong;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
[FieldOffset(0)] internal byte[] rgBytes;
internal BluetoothAddress()
{
ullLong = 0;
rgBytes = new byte[6];
}
}
/*
typedef struct _BLUETOOTH_DEVICE_INFO {
DWORD dwSize; // size, in bytes, of this structure - must be the
sizeof(BLUETOOTH_DEVICE_INFO)
BLUETOOTH_ADDRESS Address; // Bluetooth address
ULONG ulClassofDevice; // Bluetooth "Class of Device"
BOOL fConnected; // Device connected/in use
BOOL fRemembered; // Device remembered
BOOL fAuthenticated; // Device authenticated/paired/bonded
SYSTEMTIME stLastSeen; // Last time the device was seen
SYSTEMTIME stLastUsed; // Last time the device was used for other than
RNR, inquiry, or SDP
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ]; // Name of the device
} BLUETOOTH_DEVICE_INFO_STRUCT;
#define BLUETOOTH_DEVICE_INFO BLUETOOTH_DEVICE_INFO_STRUCT
typedef BLUETOOTH_DEVICE_INFO * PBLUETOOTH_DEVICE_INFO;
*/
internal struct SystemTime
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BluetoothDeviceInfo
{
[MarshalAs(UnmanagedType.U4)]
internal int dwSize;
[MarshalAs(UnmanagedType.Struct)]
internal BluetoothAddress Address;
internal ulong ulClassOfDevice;
internal bool fConnected;
internal bool fRemembered;
internal bool fAuthenticated;
internal SystemTime stLastSeen;
internal SystemTime stLastUsed;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
internal char[] szName;
internal static BluetoothDeviceInfo Create()
{
BluetoothDeviceInfo bdi = new BluetoothDeviceInfo();
//Throws an error on the next line
//"Type System.Net.Bluetooth.BluetoothDeviceInfo can not be
marshaled as an unmanaged structure; no meaningful size or offset can be
computed."
bdi.dwSize = Marshal.SizeOf(typeof(BluetoothDeviceInfo));
bdi.szName = new char[32];
return bdi;
}
}
/*
typedef struct _BLUETOOTH_DEVICE_SEARCH_PARAMS {
DWORD dwSize; // IN sizeof this structure
BOOL fReturnAuthenticated; // IN return authenticated devices
BOOL fReturnRemembered; // IN return remembered devices
BOOL fReturnUnknown; // IN return unknown devices
BOOL fReturnConnected; // IN return connected devices
BOOL fIssueInquiry; // IN issue a new inquiry
UCHAR cTimeoutMultiplier; // IN timeout for the inquiry
HANDLE hRadio; // IN handle to radio to enumerate - NULL == all radios
will be searched
} BLUETOOTH_DEVICE_SEARCH_PARAMS;
*/
[StructLayout(LayoutKind.Sequential)]
internal struct BluetoothDeviceSearchParams
{
[MarshalAs(UnmanagedType.U4)]
internal int dwSize;
internal bool fReturnAuthenticated;
internal bool fReturnRemembered;
internal bool fReturnUnknown;
internal bool fReturnConnected;
internal bool fIssueInquiry;
internal ushort cTimeoutMultiplier;
internal IntPtr hRadio;
internal static BluetoothDeviceSearchParams Create(IntPtr hRadio)
{
BluetoothDeviceSearchParams dsp = new BluetoothDeviceSearchParams();
dsp.dwSize = Marshal.SizeOf(typeof(BluetoothDeviceSearchParams) );
dsp.hRadio = hRadio;
return dsp;
}
}
/*
BluetoothFindFirstDevice(
BLUETOOTH_DEVICE_SEARCH_PARAMS * pbtsp,
BLUETOOTH_DEVICE_INFO * pbtdi
);
*/
[DllImport("bthprops.cpl")]
private static extern IntPtr BluetoothFindFirstDevice(ref
BluetoothDeviceSearchParams pbtsp, ref BluetoothDeviceInfo pbtdi);
/*
HBLUETOOTH_DEVICE_FIND hFind;
BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) };
BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) };
btsp.fReturnAuthenticated = TRUE;
btsp.fReturnRemembered = TRUE;
hFind = BluetoothFindFirstDevice( &btsp, &btdi );
*/
public void SearchDevices()
{
BluetoothDeviceSearchParams dsp =
BluetoothDeviceSearchParams.Create(phRadio);
BluetoothDeviceInfo bdi = BluetoothDeviceInfo.Create();
IntPtr x = BluetoothFindFirstDevice(ref dsp, ref bdi);
}
Thanks & Regards,
B Vidyadhar Joshi
"Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> wrote in
message news:O2S8UmXzEHA.4028@TK2MSFTNGP15.phx.gbl...[color=blue]
>B Vidyadhar Joshi,
>
> First, you should not be declaring GetLastError. To perform interop,
> the framework has to call a number of windows APIs, both before and after
> the call, which could affect the error state for the current thread.
> Because of this, the Marshal class has a static method, GetLastWin32Error,
> which you should call to get the error code.
>
> I also think that you are not making the correct declarations. Because
> you define BLUETOOTH_FIND_RADIO_PARAMS as a class, your definition in the
> API should not be ref, but just as it is (because it is a reference that
> is being passed already). Either that, or you could redefine the
> structure like this:
>
> [StructLayout(LayoutKind.Sequential)]
> public struct BLUETOOTH_FIND_RADIO_PARAMS
> {
> [MarshalAs(UnmanagedType.U4)]
> public int dwSize;
>
> // Factory to initialize instances, since you can't override default
> constructors on
> // structs.
> public static BLUETOOTH_FIND_RADIO_PARAMS Create()
> {
> // Create the instance.
> BLUETOOTH_FIND_RADIO_PARAMS retVal = new
> BLUETOOTH_FIND_RADIO_PARAMS();
>
> // Set the length parameter.
> retVal.dwSize =
> Marshal.SizeOf(typeof(BLUETOOTH_FIND_RADIO_PARAMS) );
>
> // Return.
> return retVal;
> }
> }
>
> Your declaration of BluetoothFindFirstRadio is also wrong. The second
> parameter should be ref. It should be:
>
> [DllImport("bthprops.cpl", SetLastError=true)]
> public static extern IntPtr BluetoothFindFirstRadio(
> ref BLUETOOTH_FIND_RADIO_PARAMS pbtfrp,
> ref IntPtr phRadio);
>
> The SetLastError property on the attribute indicates that interop
> should store the value of GetLastError in case you want it later.
>
> Your code ends up looking like this:
>
> public void DiscoverDevices()
> {
> BLUETOOTH_FIND_RADIO_PARAMS frp =
> BLUETOOTH_FIND_RADIO_PARAMS.Create();
> IntPtr phRadio = new IntPtr();
> BluetoothFindFirstRadio(ref frp, ref phRadio);
> int y = Marshal.GetLastWin32Error();
> }
>
> Hope this helps.
>
>
> --
> - Nicholas Paldino [.NET/C# MVP]
> -
mvp@spam.guard.caspershouse.com
>
>
>
> "B Vidyadhar Joshi" <joshibv@knowledgepointsolutions.com> wrote in message
> news:%23PeaS1WzEHA.576@TK2MSFTNGP14.phx.gbl...[color=green]
>>I was writing an Bluetooth Application which makes calls to Windows APIs.
>>I feel I'm doing something wrong with the structure. Could somebody help
>>me? The code that I'm using is pasted below:
>>
>> using System;
>> using System.Runtime.InteropServices;
>> namespace System.Net.Bluetooth
>> {
>> [StructLayout(LayoutKind.Sequential)]
>> public class BLUETOOTH_FIND_RADIO_PARAMS
>> {
>> /* typedef struct {
>> * DWORD dwSize;
>> * } BLUETOOTH_FIND_RADIO_PARAMS; */
>>
>> public UInt32 dwSize;
>> public BLUETOOTH_FIND_RADIO_PARAMS()
>> {
>> dwSize = (UInt32)Marshal.SizeOf(this);
>> }
>> }
>>
>> /*######## API Declaration
>> ################################################## #####################################
>> HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
>> BLUETOOTH_FIND_RADIO_PARAMS* pbtfrp, HANDLE* phRadio);
>> ################################################## ################################################## #########*/
>> [DllImport("bthprops.cpl")]
>> public static extern IntPtr BluetoothFindFirstRadio(ref
>> BLUETOOTH_FIND_RADIO_PARAMS pbtfrp, IntPtr phRadio);
>>
>> /*######## API Declaration
>> ################################################## #####################################
>> DWORD GetLastError(void);
>> ################################################## ################################################## #########*/
>> [DllImport("kernel32.dll")]
>> private static extern uint GetLastError();
>>
>> public void DiscoverDevices()
>> {
>> BLUETOOTH_FIND_RADIO_PARAMS frp = new
>> BLUETOOTH_FIND_RADIO_PARAMS();
>> IntPtr phRadio = new IntPtr(0);
>> BluetoothFindFirstRadio(ref frp,phRadio);
>> uint y = GetLastError();
>> }
>> }
>>
>> When I run this code, I get an error 1306 (y == 1306). The string message
>> for this error is "Indicates two revision levels are incompatible."
>>
>> The above API declarations can be found in BluetoothAPIs.h (Platform SDK
>> on WinXP SP2).
>>
>> Thanks in advance.
>>
>> B Vidyadhar Joshi.
>>[/color]
>
>[/color]