Найти общий размер массива объектов только с указателем ссылки? - PullRequest
1 голос
/ 13 июня 2011

Итак, в качестве обзора я работаю с Wlanapi, и я довольно новичок в этом (нативный apis в целом).Я сталкиваюсь с проблемой преобразования структуры из c ++ в c #.Сейчас у меня есть:

Оригинал:

typedef struct _WLAN_BSS_LIST {
    DWORD          dwTotalSize;
    DWORD          dwNumberOfItems;
    WLAN_BSS_ENTRY wlanBssEntries[1];
} WLAN_BSS_LIST, *PWLAN_BSS_LIST;

Преобразование:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct WLAN_BSS_LIST 
{
    internal uint             dwTotalSize;
    internal uint             dwNumberOfItems;
    internal WLAN_BSS_ENTRY[] wlanBssEntries;

    internal WLAN_BSS_LIST(IntPtr ppBssList)
    {
        dwNumberOfItems = (uint)Marshal.ReadInt32(ppBssList);
        //I need to set the value of dwTotalSize but I dunno how
        wlanBssEntries = new WLAN_BSS_ENTRY[dwNumberOfItems];

        for (int i = 0; i < dwNumberOfItems; i++)
        {
            IntPtr pWlanBssEntry = new IntPtr(ppBssList.ToInt32() + i * 
                Marshal.SizeOf(typeof(WLAN_BSS_ENTRY)) + 8);
            wlanBssEntries[i] = (WLAN_BSS_ENTRY)Marshal.
                                    PtrToStructure(pWlanBssEntry, 
                                        typeof(WLAN_BSS_ENTRY));
        }
    }
}

Я просто не знаю, как получить общий размер массива, на который ссылаетсяppBssList: (

Как к вашему сведению, я буду крайне разочарован, если кто-то укажет мне на существующую библиотеку.

Отредактировано для добавления оригинальной структуры

Ответы [ 2 ]

0 голосов
/ 13 июня 2011

Итак, я понял, я не знаю, о чем я думал ...

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct WLAN_BSS_LIST
{
    internal uint dwTotalSize;
    internal uint dwNumberOfItems;
    internal WLAN_BSS_ENTRY[] wlanBssEntries;

    internal WLAN_BSS_LIST(IntPtr ppBssList)
    {
        dwTotalSize = (uint)Marshal.ReadInt32(ppBssList);
        dwNumberOfItems = (uint)Marshal.ReadInt32(ppBssList, 4);
        wlanBssEntries = new WLAN_BSS_ENTRY[dwNumberOfItems];
        for (int i = 0; i < dwNumberOfItems; i++)
        {
            IntPtr pWlanBssEntry = new IntPtr(ppBssList.ToInt32() + i * 
                Marshal.SizeOf(typeof(WLAN_BSS_ENTRY)) + 8);
            wlanBssEntries[i] = (WLAN_BSS_ENTRY)Marshal.
                PtrToStructure(pWlanBssEntry, typeof(WLAN_BSS_ENTRY));
        }
    }
}

И

[StructLayout(LayoutKind.Sequential)]
public struct WLAN_BSS_ENTRY
{
    public DOT11_SSID dot11Ssid;
    public uint uPhyId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] dot11Bssid;
    public DOT11_BSS_TYPE dot11BssType;
    public DOT11_PHY_TYPE dot11BssPhyType;
    public int lRssi;
    public uint uLinkQuality;
    public bool bInRegDomain;
    public UInt16 usBeaconPeriod;
    public UInt64 ullTimestamp;
    public UInt64 ullHostTimestamp;
    public UInt16 usCapabilityInformation;
    public uint ulChCenterFrequency;
    public WLAN_RATE_SET wlanRateSet;
    public uint ulIeOffset;
    public uint ulIeSize;
}
0 голосов
/ 13 июня 2011

Я не уверен, отражает ли ваш twTotalSize объем памяти, выделенный для записей в wlanBssEntries, если так, то простого вычисления будет достаточно,

 sizeof(typeof(WLAN_BSS_ENTRY)) * dwNumberOfItems + 8

в противном случае я предлагаю вам опубликовать исходную структуру данных, может быть, есть гораздо лучшая альтернатива для маршалинга из блока памяти.

...