簡體   English   中英

將結構從C ++函數返回到C#,然后返回數組UPDATE

[英]Return a struct from a c++ function to c# then an array UPDATE

我在2個星期內閱讀了100篇以上的帖子,使自己完全困惑。 這是我在BlueSoleil堆棧上編寫的包裝程序。

在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);
};

在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);
}

錯誤3參數1:無法從'ConsoleWrapperTest.Program.BluetoothDevice'轉換為'BlueSoleilWrapper._BlueToothDevice'

所以有人可以指出我哪里出了問題。

吉姆

更新

使用以下標頭代碼編譯c ++ / cli包裝器

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

public:

    int^ GetBTD(_BlueToothDevices % btds);
};

和cpp代碼

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

現在問題在C#代碼中

var rd = new RemoteDeviceDiscovery();

_BlueToothDevices bluetoothDevices = new _BlueToothDevices();

var i = rd.GetBTD(bluetoothDevices);

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

編譯時,該語言不支持“ GetBTD”,到目前為止,我所看到的一切都無法解決。 感謝任何進一步的協助。

吉姆

似乎您使用的是C ++ \\ CLI,而不是純C ++。 如果直接使用RemoteDeviceDiscovery ,則必須實例化BLUETOOTHDEVICE ,而不是嘗試創建自己的結構。

如果由於無法公開顯示而無法使用BLUETOOTHDEVICE ,則可以為RemoteDeviceDiscovery類編寫某種適配器,它將采用您的結構並將其映射到BLUETOOTHDEVICE

好的,有一個可行的答案! 非常感謝rpeshkov,您為我指明了正確的方向,我很高興從中學到了一些東西。

在標題中

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

在cpp代碼中

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

最后是C#代碼(這當然只是開發框架的簡單測試)

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;

我建議查看定義了類RemoteDeviceDiscovery的程序集(在Microsoft Visual Studio中為F12),看看是否可以找到該程序集的BlueSoleilWrapper._BlueToothDevice定義。 然后直接使用該定義。 ConsoleWrapperTest.Program.BluetoothDevice永遠不會映射到BlueSoleilWrapper._BlueToothDevice ,無論您的定義與程序集中的定義多么接近。

替換.cpp代碼

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM