C# вызов WinAPI маршаллинг
От: MikeCpp  
Дата: 16.05.09 16:49
Оценка:
Не могу разобраться как передать из С# в WinAPI функцию указатель на структуру, содержащую строки, выделив при этом под них память. Помогить, плиз.

Исходный код на С++ выглядит примерно так (читаем информащию из ListControl'a находящегося в другом процессе):

    LPVOID pMemLVITEM = VirtualAllocEx( hProcess, 0, LV_BUF_SIZE*sizeof(TCHAR) + sizeof(LVITEM), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );

    LVITEM Item;
    Item.iSubItem = 1;
    Item.pszText = (TCHAR*)pMemLVITEM + sizeof(LVITEM);
    Item.cchTextMax = LV_BUF_SIZE - 1;

    WriteProcessMemory( hProcess, pMemLVITEM, &Item, sizeof(LVITEM), NULL );
    LRESULT len = SendMessage( hList, LVM_GETITEMTEXT, nIndex, (LPARAM)pMemLVITEM );


Попытка перевести на C#:

        [DllImport("user32")]
        static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("kernel32.dll")]
        static extern IntPtr VirtualAllocEx(int hProcess, IntPtr lpAdress, int size, int flAllocationType, int flProtect);
        [DllImport("kernel32.dll")]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);

        [StructLayout(LayoutKind.Sequential)]
        public struct ListViewItem
        {
            uint mask;
            int iItem;
            public int iSubItem;
            uint state;
            uint stateMask;
            public StringBuilder pszText;
            public int cchTextMax;
            int iImage;
            long lParam;
            int iIndent;
            int iGroupId;
            uint cColumns;
            uint puColumns;
        }

        IntPtr pListItemMemory = VirtualAllocEx(hProcess, IntPtr.Zero, 1024 + 40, 0x3000, 0x04); // 0x3000 == MEM_RESERVE | MEM_COMMIT, 0x04 == PAGE_READWRITE, 40 == sizeof(LVITEM)

        ListViewItem listItem = new ListViewItem();
        listItem.iSubItem = 1;
        listItem.pszText.Capacity = 1024;
        listItem.cchTextMax = 1024;

        IntPtr pListItem = new IntPtr(&listItem);

        bool bWrite = WriteProcessMemory(hProcess, pListItemMemory, pListItem, 1024, IntPtr.Zero);


Вопросы такие: если pszText объявлять как StringBuilder не берётся указатель от структуры, так как там строкове поля. Если делать IntPtr то не ясно как присвоить ему значение pListItemMemory + sizeof(ListViewItem).

Нужна помощь по переводе приведённого выше куска кода С++ на С#.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.