powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как мне в .Net правильно создать указатель на массив указателей?
3 сообщений из 3, страница 1 из 1
Как мне в .Net правильно создать указатель на массив указателей?
    #38980430
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оригинальный код VB6:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Public ahpsp(0 To 8) As Long
...
  Dim psp As PROPSHEETPAGE
...
  ahpsp(0) = CreatePropertySheetPage(psp) 'указатель на page0
...
  ahpsp(8) = CreatePropertySheetPage(psp) 'указатель на page8

  Dim psh As PROPSHEETHEADER
  With psh
...
    .Union_ppsp_phpage = VarPtr(ahpsp(0)) 'т.е.сюда я должен пихнуть указатель на ahpsp
...
    .Union_nStartPage_pStartPage = 0
    .nPages = 9 'это к-во PropertySheetPage, каждой странице соответствует указатель - элемент массива ahpsp
  End With
  
  PropertySheet psh 'собственно вызов визарда




Вот как я пытаюсь сделать то же самое в .Net
Так как ниже, работает только для одной страницы.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
  Public ahpsp(0 To 8) As IntPtr
 ...
    Dim psp As New PROPSHEETPAGE
...
   ahpsp(0) = CreatePropertySheetPage(psp) 'указатель на page0
...
   ahpsp(8) = CreatePropertySheetPage(psp) 'указатель на page8

    Dim psh As New PROPSHEETHEADER
    With psh
...
      .Union_ppsp_phpage = Marshal.AllocHGlobal(IntPtr.Size)
       Marshal.WriteIntPtr(.Union_ppsp_phpage, ahpsp(0))
...
      .Union_nStartPage_pStartPage = New IntPtr(0)
      .nPages = 1
    End With

    PropertySheet(psh)
    Marshal.FreeHGlobal(psh.Union_ppsp_phpage)



Если сделать .nPages = 9 как мне надо, то ошибка доступа к памяти (очевидно в .Union_ppsp_phpage при таком коде сидит только первый элемент массива)

Попытался вот так вот:
Код: vbnet
1.
2.
3.
4.
5.
      .Union_ppsp_phpage = Marshal.AllocHGlobal(IntPtr.Size * 9)
      For i As Integer = 0 To 8
        Marshal.WriteIntPtr(.Union_ppsp_phpage + IntPtr.Size * i, ahpsp(i))
      Next
      .nPages = 9



Но во-первых, не уверен что правильно,
во-вторых плюсование IntPtr-ов не уверен что полностью законно и корректно (.Union_ppsp_phpage + IntPtr.Size * i)
а в третьих при компиляции кода в .Net2 это плюсование еще и выдает ошибку.

Как правильно извернуться?

Т.е. надо чтобы в .Union_ppsp_phpage сидел указатель на полный массив ahpsp(0 To 8) As IntPtr, а не только на первый его элемент
При этом код должен быть инвариантен относит. x64/x86 и относит. .Net4.5/.Net2, дабы не иметь сложности в дальнейшем.

в структурах PROPSHEETPAGE/PROPSHEETHEADER у меня ошибок c IntPtr/Integer нет, уже покопался с этим, поэтому об этом не спрашиваю.
...
Рейтинг: 0 / 0
Как мне в .Net правильно создать указатель на массив указателей?
    #38980489
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверно все же делаю правильно.
Если >=.Net4 то можно так
Код: vbnet
1.
2.
3.
4.
     .Union_ppsp_phpage = Marshal.AllocHGlobal(IntPtr.Size * 9)
      For i As Integer = 0 To 8
        Marshal.WriteIntPtr(IntPtr.Add(.Union_ppsp_phpage, IntPtr.Size * i), ahpsp(i))
      Next


Ну а коль мне нужна совместимость с .Net2, то думаю вот так не подведет:
Код: vbnet
1.
2.
3.
4.
      .Union_ppsp_phpage = Marshal.AllocHGlobal(IntPtr.Size * 9)
      For i As Integer = 0 To 8
        Marshal.WriteIntPtr(New IntPtr(.Union_ppsp_phpage.ToInt64() + IntPtr.Size * i), ahpsp(i))
      Next


Хотя конечно при x86-исполнении ToInt64() избыточно, да и бог с ним.
...
Рейтинг: 0 / 0
Как мне в .Net правильно создать указатель на массив указателей?
    #38980499
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фиг с ним, напишу лучше нормально:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
      .Union_ppsp_phpage = Marshal.AllocHGlobal(IntPtr.Size * 9)
      Select Case IntPtr.Size
        Case 8 'x64
          For i As Integer = 0 To 8
            Marshal.WriteIntPtr(New IntPtr(.Union_ppsp_phpage.ToInt64() + IntPtr.Size * i), ahpsp(i))
          Next
        Case Else '4, 32-бит
          For i As Integer = 0 To 8
            Marshal.WriteIntPtr(New IntPtr(.Union_ppsp_phpage.ToInt32() + IntPtr.Size * i), ahpsp(i))
          Next
      End Select
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как мне в .Net правильно создать указатель на массив указателей?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]