C++ structure to C# structure - help needed

B

B Vidyadhar Joshi

I have converted a few C++ structures to C# structures. However, when I use
them in the code, I get errors in "internal static BluetoothDeviceInfo
Create()". I feel I'm doing something wrong while converting the union.
Could someone help please?

/*
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;
}
}

Thanks & Regards,

B Vidyadhar Joshi.
 
G

Guest

I think you're going to have to add an attribute that tells it the size of
the BluetoothAddress class explicitly so that when you call sizeof against
the BluetoothDeviceInfo it knows how to add things up (since you referenced
the BluetoothAddress class internally)

Since you're telling it that you'll explicitly manage the layout of a
BluetoothAddress, and you're starting different fields at the same offset, it
really has no way to know how big the thing is. If you tag it as being a
constanct size of 8, then it will know.
 
B

B Vidyadhar Joshi

Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly System.Net.Bluetooth,
Version=1.0.1787.23495, Culture=neutral, PublicKeyToken=null because it
contains an object field at offset 0 that is incorrectly aligned or
overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct (union).
But can't figure out what is wrong.

TIA.

B Vidyadhar Joshi
 
W

Willy Denoyette [MVP]

B Vidyadhar Joshi said:
Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly System.Net.Bluetooth,
Version=1.0.1787.23495, Culture=neutral, PublicKeyToken=null because it
contains an object field at offset 0 that is incorrectly aligned or
overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.

This won't work, you can't overlap a non-object field (a value) with an
object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same as C
(or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your address as
a byte[8] and use BitConverter.ToUInt64 to convert it to a ulong.

Willy.
 
B

B Vidyadhar Joshi

Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can you
bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi



Willy Denoyette said:
B Vidyadhar Joshi said:
Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly System.Net.Bluetooth,
Version=1.0.1787.23495, Culture=neutral, PublicKeyToken=null because it
contains an object field at offset 0 that is incorrectly aligned or
overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.

This won't work, you can't overlap a non-object field (a value) with an
object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same as C
(or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your address
as a byte[8] and use BitConverter.ToUInt64 to convert it to a ulong.

Willy.
 
W

Willy Denoyette [MVP]

const int BLUETOOTH_MAX_NAME_SIZE = 255;

[StructLayout(LayoutKind.Sequential)]
struct _BLUETOOTH_RADIO_INFO {
internal uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
internal byte[] address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
BLUETOOTH_MAX_NAME_SIZE )]
internal string szName;
internal uint ulClassofDevice;
internal ushort lmpSubversion;
internal ushort manufacturer;
// Return a ulong from the 6 byte array, respecting the byte order,
don't know why one would ever need this in ulong form though..
// If byte order is not important (but I guess it is) you could use
BitConverter.ToUInt64(address, 0);
internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}
}


Usage:

_BLUETOOTH_RADIO_INFO bi = new _BLUETOOTH_RADIO_INFO();
bi.address = new byte[] {34, 56, 56, 234, 12, 34};
Console.WriteLine("{0:x}", bi.BTH_ADDR);

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can you
bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi



Willy Denoyette said:
B Vidyadhar Joshi said:
Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly
System.Net.Bluetooth, Version=1.0.1787.23495, Culture=neutral,
PublicKeyToken=null because it contains an object field at offset 0 that
is incorrectly aligned or overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.

This won't work, you can't overlap a non-object field (a value) with an
object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same as C
(or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your address
as a byte[8] and use BitConverter.ToUInt64 to convert it to a ulong.

Willy.
 
B

B Vidyadhar Joshi

Hi Willy,

Thanks for the help.

When I implemented your suggested code, I get a compile error on the line "
BitConverter.ToUInt64(address, 0);":

Invalid token '(' in class, struct, or interface member declaration

TIA

B Vidyadhar Joshi


Willy Denoyette said:
const int BLUETOOTH_MAX_NAME_SIZE = 255;

[StructLayout(LayoutKind.Sequential)]
struct _BLUETOOTH_RADIO_INFO {
internal uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
internal byte[] address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
BLUETOOTH_MAX_NAME_SIZE )]
internal string szName;
internal uint ulClassofDevice;
internal ushort lmpSubversion;
internal ushort manufacturer;
// Return a ulong from the 6 byte array, respecting the byte order,
don't know why one would ever need this in ulong form though..
// If byte order is not important (but I guess it is) you could use
BitConverter.ToUInt64(address, 0);
internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}
}


Usage:

_BLUETOOTH_RADIO_INFO bi = new _BLUETOOTH_RADIO_INFO();
bi.address = new byte[] {34, 56, 56, 234, 12, 34};
Console.WriteLine("{0:x}", bi.BTH_ADDR);

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can
you bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi



Willy Denoyette said:
message Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly
System.Net.Bluetooth, Version=1.0.1787.23495, Culture=neutral,
PublicKeyToken=null because it contains an object field at offset 0
that is incorrectly aligned or overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.


This won't work, you can't overlap a non-object field (a value) with an
object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same as
C (or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your address
as a byte[8] and use BitConverter.ToUInt64 to convert it to a ulong.

Willy.
 
W

Willy Denoyette [MVP]

Dont use the BitConverter it won't work, you should use the following:

internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Thanks for the help.

When I implemented your suggested code, I get a compile error on the line
" BitConverter.ToUInt64(address, 0);":

Invalid token '(' in class, struct, or interface member declaration

TIA

B Vidyadhar Joshi


Willy Denoyette said:
const int BLUETOOTH_MAX_NAME_SIZE = 255;

[StructLayout(LayoutKind.Sequential)]
struct _BLUETOOTH_RADIO_INFO {
internal uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
internal byte[] address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
BLUETOOTH_MAX_NAME_SIZE )]
internal string szName;
internal uint ulClassofDevice;
internal ushort lmpSubversion;
internal ushort manufacturer;
// Return a ulong from the 6 byte array, respecting the byte order,
don't know why one would ever need this in ulong form though..
// If byte order is not important (but I guess it is) you could use
BitConverter.ToUInt64(address, 0);
internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}
}


Usage:

_BLUETOOTH_RADIO_INFO bi = new _BLUETOOTH_RADIO_INFO();
bi.address = new byte[] {34, 56, 56, 234, 12, 34};
Console.WriteLine("{0:x}", bi.BTH_ADDR);

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can
you bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi




message Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly
System.Net.Bluetooth, Version=1.0.1787.23495, Culture=neutral,
PublicKeyToken=null because it contains an object field at offset 0
that is incorrectly aligned or overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.


This won't work, you can't overlap a non-object field (a value) with an
object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same as
C (or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your
address as a byte[8] and use BitConverter.ToUInt64 to convert it to a
ulong.

Willy.
 
B

B Vidyadhar Joshi

Hi Willy,

Thanks for the help. I understood it later that BitConverter should not be
used.

When I use this struct in the function, it compiles fine and runs. But the
function returns an error ERROR_REVISION_MISMATCH which is documented in
Platform SDK documentation as "The dwSize member of the BLUETOOTH_RADIO_INFO
structure pointed to by pRadioInfo is invalid.". Any idea on this one?

B Vidyadhar Joshi.


Willy Denoyette said:
Dont use the BitConverter it won't work, you should use the following:

internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Thanks for the help.

When I implemented your suggested code, I get a compile error on the line
" BitConverter.ToUInt64(address, 0);":

Invalid token '(' in class, struct, or interface member declaration

TIA

B Vidyadhar Joshi


Willy Denoyette said:
const int BLUETOOTH_MAX_NAME_SIZE = 255;

[StructLayout(LayoutKind.Sequential)]
struct _BLUETOOTH_RADIO_INFO {
internal uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
internal byte[] address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
BLUETOOTH_MAX_NAME_SIZE )]
internal string szName;
internal uint ulClassofDevice;
internal ushort lmpSubversion;
internal ushort manufacturer;
// Return a ulong from the 6 byte array, respecting the byte order,
don't know why one would ever need this in ulong form though..
// If byte order is not important (but I guess it is) you could use
BitConverter.ToUInt64(address, 0);
internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}
}


Usage:

_BLUETOOTH_RADIO_INFO bi = new _BLUETOOTH_RADIO_INFO();
bi.address = new byte[] {34, 56, 56, 234, 12, 34};
Console.WriteLine("{0:x}", bi.BTH_ADDR);

Willy.

message Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can
you bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi




message Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly
System.Net.Bluetooth, Version=1.0.1787.23495, Culture=neutral,
PublicKeyToken=null because it contains an object field at offset 0
that is incorrectly aligned or overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.


This won't work, you can't overlap a non-object field (a value) with
an object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same
as C (or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your
address as a byte[8] and use BitConverter.ToUInt64 to convert it to a
ulong.

Willy.
 
B

B Vidyadhar Joshi

Hi Willy,

You have clubbed the BluetoothAddress structure into BluetoothRadioInfo
which adds one more member to the structure. Will this not report a wrong
structure size when Marshal.SizeOf() is used?

B Vidyadhar Joshi

Willy Denoyette said:
Dont use the BitConverter it won't work, you should use the following:

internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}

Willy.

B Vidyadhar Joshi said:
Hi Willy,

Thanks for the help.

When I implemented your suggested code, I get a compile error on the line
" BitConverter.ToUInt64(address, 0);":

Invalid token '(' in class, struct, or interface member declaration

TIA

B Vidyadhar Joshi


Willy Denoyette said:
const int BLUETOOTH_MAX_NAME_SIZE = 255;

[StructLayout(LayoutKind.Sequential)]
struct _BLUETOOTH_RADIO_INFO {
internal uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
internal byte[] address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
BLUETOOTH_MAX_NAME_SIZE )]
internal string szName;
internal uint ulClassofDevice;
internal ushort lmpSubversion;
internal ushort manufacturer;
// Return a ulong from the 6 byte array, respecting the byte order,
don't know why one would ever need this in ulong form though..
// If byte order is not important (but I guess it is) you could use
BitConverter.ToUInt64(address, 0);
internal ulong BTH_ADDR {
get {
return (ulong)address[5] + ((ulong)address[4] << 8)
+ ((ulong)address[3] << 16) + ((ulong)address[2] << 24)
+ ((ulong)address[1] << 32) + ((ulong)address[0] << 40);
}
}
}


Usage:

_BLUETOOTH_RADIO_INFO bi = new _BLUETOOTH_RADIO_INFO();
bi.address = new byte[] {34, 56, 56, 234, 12, 34};
Console.WriteLine("{0:x}", bi.BTH_ADDR);

Willy.

message Hi Willy,

Sorry for the ignorance; but I couldn't understand what you meant. Can
you bea bit more verbose or just convert the following struct?

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 )

typedef struct _BLUETOOTH_RADIO_INFO {
DWORD dwSize;
BLUETOOTH_ADDRESS address;
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ];
ULONG ulClassofDevice;
USHORT lmpSubversion;
USHORT manufacturer;
} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO;

Thanks for the help.

B Vidyadhar Joshi




message Hi Scott,

Thanks for the reply.

Now, I got the thing working but I get a new error:

An unhandled exception of type 'System.TypeLoadException' occurred in
System.Net.Bluetooth.exe

Additional information: Could not load type
System.Net.Bluetooth.BluetoothAddress from assembly
System.Net.Bluetooth, Version=1.0.1787.23495, Culture=neutral,
PublicKeyToken=null because it contains an object field at offset 0
that is incorrectly aligned or overlapped by a non-object field.

Any idea? I guess it is the error with the BluetoothAddress struct
(union). But can't figure out what is wrong.


This won't work, you can't overlap a non-object field (a value) with
an object field in .NET, they are allocated differently.
One common mistake people make is to think .NET structs are the same
as C (or C++) structs, they are NOT .

To solve your problem you don't need a struct, just declare your
address as a byte[8] and use BitConverter.ToUInt64 to convert it to a
ulong.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top