0

I have read through maybe 100+ posts on this over 2 weeks and have got myself totally confused. This is for a wrapper i'm writing over the BlueSoleil stack.

In c++

typedef char BTINT8;
typedef unsigned char BTUINT8;
typedef unsigned char BTUCHAR; /* extended ASII character, 0 - 255 */
typedef unsigned char BTBOOL;
typedef short BTINT16;
typedef unsigned short BTUINT16;
typedef long BTINT32;
typedef unsigned long BTUINT32;
typedef void * BTLPVOID;

typedef BTUINT32 BTDEVHDL;
typedef BTUINT32 BTSVCHDL;
typedef BTUINT32 BTCONNHDL;
typedef BTUINT32 BTSHCHDL;
typedef BTUINT32 BTSDKHANDLE;

typedef struct _BlueToothDevice
{
    BTDEVHDL rmt_device_handle;
    BTINT32  rmt_device_num;
    BTUINT32 rmt_device_class;
    BTUINT8  rmt_device_name[64];

} BLUETOOTHDEVICE;

typedef struct _BlueToothDevices
{
    BTUINT32 num_rmt_devices;
    BLUETOOTHDEVICE rmt_btd[100];
} BLUETOOTHDEVICES;

public ref class RemoteDeviceDiscovery
{       
public:
    int GetBTD(BLUETOOTHDEVICE btd);
};

In C#

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct BluetoothDevice
    {
        [MarshalAs(UnmanagedType.SysUInt)]
        public UInt32 rmt_device_handle;
        [MarshalAs(UnmanagedType.SysInt)]
        public Int32 rmt_device_num;
        [MarshalAs(UnmanagedType.SysUInt)]
        public UInt32 rmt_device_class;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 248)]
        public IntPtr rmt_device_name;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct BluetoothDevices
    {
        [MarshalAs(UnmanagedType.SysUInt)]
        public UInt32 num_rmt_devices;
        [MarshalAs(UnmanagedType.ByValArray)]
        public List<BluetoothDevice> BluetoothDeviceInfo;
    }

static void Main()
{
    var rd = new RemoteDeviceDiscovery();

    BluetoothDevice bluetoothDevice = new BluetoothDevice();
    var i = rd.GetBTD(ref bluetoothDevice);
}

Error 3 Argument 1: cannot convert from 'ConsoleWrapperTest.Program.BluetoothDevice' to 'BlueSoleilWrapper._BlueToothDevice'

So can someone point out where I have gone wrong please.

Jim

UPDATE

Have the c++/cli wrapper compiling with the following header code

public ref class RemoteDeviceDiscovery
{
    /* Remote Device Discovery */

public:

    int^ GetBTD(_BlueToothDevices % btds);
};

and cpp code

array<Byte>^ MakeManagedArray(unsigned char* input, int len)
{
    array<Byte>^ result = gcnew array<Byte>(len);
    for (int i = 0; i < len; i++)
    {
        result[i] = input[i];
    }
    return result;
}

int^ RemoteDeviceDiscovery::GetBTD(_BlueToothDevices % btds)
{
    unsigned char name[] = "Test";

    _BlueToothDevice entry;

    btds.num_rmt_devices = 1;
    entry.rmt_device_class = 1;
    entry.rmt_device_handle = 2;
    entry.rmt_device_num = 3;
    entry.rmt_device_name = MakeManagedArray(name, sizeof(name));

    btds.rmt_btd[0] = gcnew _BlueToothDevice();
    btds.rmt_btd[0] = %entry;

    return 99;
}

Problem is now in the C# code

var rd = new RemoteDeviceDiscovery();

_BlueToothDevices bluetoothDevices = new _BlueToothDevices();

var i = rd.GetBTD(bluetoothDevices);

var rmt_device_handle = bluetoothDevices.rmt_btd[0].rmt_device_handle;

When compiling I get 'GetBTD' is not supported by the language and everything I have seen so far as solutions hasn't worked. Appreciate any further assistance.

Jim

4 Answers 4

1

Seems like you're using C++\CLI, not plain C++. If you're using RemoteDeviceDiscovery directly then you have to instantiate BLUETOOTHDEVICE, not trying to create your own structure.

If you can't use BLUETOOTHDEVICE because it's not publicly visible, you can write some sort of adapter for RemoteDeviceDiscovery class that will be taking your structure and mapping it on BLUETOOTHDEVICE.

Sign up to request clarification or add additional context in comments.

3 Comments

rpeshkov, Been awhile since I did any c++ coding ! The two structs BLUETOOTHDEVICE and BLUETOOTHDEVICES are in my wrapper code. How do I make them public to I can instantiate an instance in the C# code ?
Jim, googled about C++\CLI structs. I guess you need to define them as public value struct to make them managed and to be able to use them in C# code. Structs in your code are native (not managed) C++ structs.
Ok got the new managed classes worked out. Now to get the functions sorted out in the .cpp public ref class _BlueToothDevice { public: _BlueToothDevice(){} BTDEVHDL rmt_device_handle; BTINT32 rmt_device_num; BTUINT32 rmt_device_class; array<BTUINT8>^ rmt_device_name = gcnew array<BTUINT8>(64); }; public ref class _BlueToothDevices { public: _BlueToothDevices(){} BTUINT32 num_rmt_devices; array<_BlueToothDevice^>^ rmt_btd = gcnew array<_BlueToothDevice^>(100); };
1

Ok, got a working answer ! Many thanks to rpeshkov you pointed me in the right direction and i'm glad I learnt something from it all.

In the header

public ref class RemoteDeviceDiscovery
{
    /* Remote Device Discovery */
public:
    int GetBTD(_BlueToothDevices ^% btds);
};

In the cpp code

int RemoteDeviceDiscovery::GetBTD(_BlueToothDevices ^% btds)
{
    unsigned char name0[] = "Test0";
    unsigned char name1[] = "Test1";

    _BlueToothDevice^ entry = gcnew _BlueToothDevice();

    entry->rmt_device_class = 1;
    entry->rmt_device_handle = 2;
    entry->rmt_device_num = 3;
    entry->rmt_device_name = MakeManagedArray(name0, sizeof(name0));

    btds->num_rmt_devices = 2;
    btds->rmt_btd[0] = gcnew _BlueToothDevice();
    btds->rmt_btd[0] = entry;

    entry = gcnew _BlueToothDevice();

    entry->rmt_device_class = 4;
    entry->rmt_device_handle = 5;
    entry->rmt_device_num = 6;
    entry->rmt_device_name = MakeManagedArray(name1, sizeof(name1));

    btds->rmt_btd[1] = gcnew _BlueToothDevice();
    btds->rmt_btd[1] = entry;

    return 99;
}

and finally in the C# code (this is of course just a bare bones test to development a framework)

var rd = new RemoteDeviceDiscovery();

_BlueToothDevices bluetoothDevices = new _BlueToothDevices();

var i = rd.GetBTD(ref bluetoothDevices);

var rmt_device_handle = bluetoothDevices.rmt_btd[0].rmt_device_handle;

2 Comments

Damm ! There's a bug in the .cpp code. I think since entry is passed to the array by ref it of course only shows the last. Didn't spot that.
Fixed. See amendment below. Also edited the cpp code above.
0

I suggest looking in the assembly that defines the class RemoteDeviceDiscovery (F12 in Microsoft Visual Studio), and see if you can find that assembly's definition of BlueSoleilWrapper._BlueToothDevice. Then use that definition directly. ConsoleWrapperTest.Program.BluetoothDevice will never map to BlueSoleilWrapper._BlueToothDevice, regardless of how close your definition matches the one in the assembly.

Comments

0

Replacement .cpp code

int RemoteDeviceDiscovery::GetBTD(_BlueToothDevices ^% btds)
{
    unsigned char name0[] = "Test0";
    unsigned char name1[] = "Test1";

    _BlueToothDevice^ entry = gcnew _BlueToothDevice();

    entry->rmt_device_class = 1;
    entry->rmt_device_handle = 2;
    entry->rmt_device_num = 3;
    entry->rmt_device_name = MakeManagedArray(name0, sizeof(name0));

    btds->num_rmt_devices = 2;
    btds->rmt_btd[0] = gcnew _BlueToothDevice();
    btds->rmt_btd[0] = entry;

    entry = gcnew _BlueToothDevice();

    entry->rmt_device_class = 4;
    entry->rmt_device_handle = 5;
    entry->rmt_device_num = 6;
    entry->rmt_device_name = MakeManagedArray(name1, sizeof(name1));

    btds->rmt_btd[1] = gcnew _BlueToothDevice();
    btds->rmt_btd[1] = entry;

    return 99;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.