#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-разрядное) из-за этой ссылки на функцию.