Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ structure to C# structure - help needed

183 views
Skip to first unread message

B Vidyadhar Joshi

unread,
Nov 20, 2004, 12:59:19 AM11/20/04
to
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.


B Vidyadhar Joshi

unread,
Nov 22, 2004, 2:34:40 AM11/22/04
to
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

"Scott" <Sc...@discussions.microsoft.com> wrote in message
news:638D6133-8607-48D8...@microsoft.com...
>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.
>


Willy Denoyette [MVP]

unread,
Nov 22, 2004, 5:48:28 AM11/22/04
to

"B Vidyadhar Joshi" <jos...@knowledgepointsolutions.com> wrote in message
news:%23U5r7WG...@TK2MSFTNGP14.phx.gbl...

> 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 Vidyadhar Joshi

unread,
Nov 22, 2004, 6:35:15 AM11/22/04
to
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 [MVP]" <willy.d...@pandora.be> wrote in message
news:%23TlGPDI...@TK2MSFTNGP15.phx.gbl...

Willy Denoyette [MVP]

unread,
Nov 22, 2004, 8:07:32 AM11/22/04
to
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" <jos...@knowledgepointsolutions.com> wrote in message

news:eDKBYdI0...@TK2MSFTNGP11.phx.gbl...

B Vidyadhar Joshi

unread,
Nov 22, 2004, 9:01:12 AM11/22/04
to
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 [MVP]" <willy.d...@pandora.be> wrote in message

news:%23YG68QJ...@tk2msftngp13.phx.gbl...

Willy Denoyette [MVP]

unread,
Nov 22, 2004, 12:19:41 PM11/22/04
to
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" <jos...@knowledgepointsolutions.com> wrote in message

news:%230Gx7uJ...@TK2MSFTNGP15.phx.gbl...

B Vidyadhar Joshi

unread,
Nov 23, 2004, 12:01:45 AM11/23/04
to
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 [MVP]" <willy.d...@pandora.be> wrote in message

news:u8qF2dL0...@TK2MSFTNGP14.phx.gbl...

B Vidyadhar Joshi

unread,
Nov 23, 2004, 3:02:28 AM11/23/04
to
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 [MVP]" <willy.d...@pandora.be> wrote in message

news:u8qF2dL0...@TK2MSFTNGP14.phx.gbl...

0 new messages