Переход на VB.NET: какой тип данных использовать для «hcontext» в проекте x64?

#vb.net #vb6 #64-bit #vb6-migration #type-conversion

#vb.net #vb6 #64-разрядный #vb6-миграция #преобразование типов

Вопрос:

У меня есть старый проект VB6.Теперь я переношу его в VB.Net на vs2008 и платформе решения теперь я должен использовать 64-битную версию.В старом коде переменная hContext была объявлена как целое число.

  Dim hContext As Integer
  

И используется как:

 Dim rc As Integer
dwScope = SCARD_SCOPE_USER
rc = SCardEstablishContext(dwScope, 0, 0, hContext)
  

Когда я отлаживаю код, hContext создает проблему.
Это связано с тем, что он определяется как целое число (32 бита).

Теперь проблема в том, «Какой тип данных я должен использовать для hContext»? Я также использовал другой тип данных, такой как Long, ULong, IntPtr….

ОБРАТИТЕ ВНИМАНИЕ, что при отладке кода hcontext принимает 4-байтовый адрес. но в 64-битном я принимаю hContext как IntPtr, который зависит от платформы, но он показывает только 1-байтовый адрес. И я не могу установить соединение.

Комментарии:

1. Я считаю, что Long — это 64-разрядный целочисленный тип.

2. Да, вы правы, но это не работает.

3. Архитектура не влияет на размер переменных. и целое число равно 32 битам в системах x64 и x86 (64-разрядные и 32-разрядные системы).

4. Вы получили неверный результат при использовании Long или ULong ?

Ответ №1:

Я подозреваю, что вопрос заключается в том, «какова правильная подпись для SCardEstablishContext в 64-разрядном проекте?»

Сигнатура C WinAPI выглядит следующим образом:

 LONG WINAPI SCardEstablishContext(
  __in   DWORD dwScope,
  __in   LPCVOID pvReserved1,
  __in   LPCVOID pvReserved2,
  __out  LPSCARDCONTEXT phContext
);
  

Типы указателей («LP …») должны быть IntPtr , а типы LONG / DWORD должны соответствовать Integer — это будет правильно для вызова WinAPI в 32-разрядной или 64-разрядной сборке. (В некоторых случаях неплохо указать тип управляемой структуры вместо IntPtr и позволить .Сетевая совместимость / pinvoke автоматически все маршалирует.)

pinvoke.иногда помогает net — см. pinvoke.net: SCardEstablishConnection и * обратите внимание, как VB.NET подпись вверху неправильная — но необходимо соблюдать осторожность, потому что определения иногда неверны и / или неполны 😉

Правильная подпись pinvoke для непрозрачного значения контекста является:

 <DllImport("winscard.dll", SetLastError:=True)>
Public Shared Function SCardEstablishContext(
    dwScope as Integer,
    pvReserved1 as IntPtr,
    pvReserved2 as IntPtr,
    <out>() phContext as IntPtr) As Integer
End Function
  

Удачного кодирования.

Комментарии:

1. @vikky Убедитесь, что подпись соответствует приведенной выше — не все являются целочисленными, не все являются IntPtr ; это зависит от того, как они определены в C WinAPI. Если все еще существует определенная ошибка во время выполнения, опубликуйте конкретное исключение в исходном сообщении.

Ответ №2:

Целое число в VB.Net определяется как 32 бита, даже при запуске в 64-битном процессе.

Из документов MSDN:

Содержит 32-разрядные (4-байтовые) целые числа со знаком, значение которых варьируется от -2 147 483 648 до 2 147 483 647.

Ваша SCardEstablishContext() функция, вероятно, вызывает неуправляемый код, который должен быть 32-битным. Поэтому я бы использовал Integer.

Возможно, вам также придется указать решение x86 (32-разрядное) (а не любое CPU или x64 / 64-разрядное) из-за этой ссылки на функцию.