После некоторых исследований я перевел
pHandle = IntPtr.Zero;
пожаловать в Delphi
var
pHandle: Pointer;
Когда я $314328
для отладки в Delphi, я получаю $314328
, когда я $314328
для отладки на C sharp, я получаю значение Integer 134180640
. Может ли кто-нибудь сказать мне, как сделать правильный перевод в Delphi?
Функция Dll, которую я вызываю в Delphi:
function SAAT_Open(pHandle: Pointer): Boolean; stdcall;
Функция C sharp:
[DllImport("RFIDAPI.dll", EntryPoint = "SAAT_Open")]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool SAAT_Open(IntPtr pHandle);
После некоторых исследований я перевел
pHandle = IntPtr.Zero;
пожаловать в Delphi
var pHandle: Pointer;
Может ли кто-нибудь сказать мне, как сделать правильный перевод в Delphi?
Синтаксис С# позволяет инициализировать переменную в том же самом заявлении, что вы объявляете переменную:
IntPtr Handle = IntPtr.Zero;
В Delphi вы не можете инициализировать локальную переменную при ее объявлении. Поэтому вам нужно объявить об этом, а затем инициализировать его:
var
Handle: Pointer;
....
Handle := nil;
Пока вы не назначаете локальную переменную неуправляемого типа, ее значение не определено.
Однако, если вы передадите nil
на SAAT_Open
тогда он не сработает. Функция ожидает ненулевой дескриптор. Итак, инициализация до nil
не поможет вам. Вам нужно сделать больше. Вам нужно вызвать функцию, которая дает новый дескриптор. Это SAAT_TCPInit
. Код С#, который вы показываете, который инициализирует дескриптор нулевому значению, делает это без необходимости. Возможно, это так, потому что SAAT_TCPInit
был ошибочно переведен для использования параметра ref
для дескриптора, а не для правильного перевода, который был бы параметром out
.
Хотя приведенное выше отвечает на заданный вами вопрос, это не поможет решить вашу проблему. Вам не нужен нулевой дескриптор, вам нужен фактический дескриптор.
Когда я ломаю для отладки в Delphi, я получаю $ 314328, когда я ломаю для отладки на C sharp, я получаю значение Integer 134180640.
Ну, после pHandle = IntPtr.Zero
вы абсолютно не увидите значение 134180640
в С#. Вы увидите значение 0
. Должен быть другой код, который инициализирует дескриптор. Предположительно, вызов SAAT_TCPInit
. Вам нужно сделать этот звонок. Я верю, что вы это делаете.
Ручка не обязательно будет иметь такое же значение при последующих запусках вашей программы. И не обязательно иметь одинаковое значение в каждой другой программе. На самом деле дескриптор представляет собой динамически выделенный указатель, и его адрес варьируется от одного прогона к другому. Поэтому не стоит беспокоиться о том, меняется ли это, как вы это заметили. Если SAAT_TCPInit
возвращает True
чтобы указать успех, тогда значение дескриптора будет действительным.
$
в одном из ваших предыдущих вопросов. Я не понимаю, почему вы не принимаете ответы или не отвечаете на вопросы, которые мы вам задаем. Возможно, вы могли бы просмотреть их все, принять лучшие ответы и по пути узнать о префиксе $
. Я думаю, что я ответил на вопрос, который вы задали здесь. Не могли бы вы сделать мне одолжение и ответить на этот комментарий.
В.NET IntPtr представляет собой представление типа указателя, которое реализуется под капотом целым числом, потому что оно не может быть фактическим указателем (ссылкой).NET, потому что нужно управлять реальными ссылками. Но это тоже не может быть реальное целое, или вы можете сделать математику на нем, что является хорошим способом получить повреждение памяти. (ПРИМЕЧАНИЕ. Это ограничение может быть или не существовать, в зависимости от того, какая версия С# и/или CLR вы используете.)
Но поскольку вы не можете рассматривать IntPtr как целое число, единственные полезные вещи, которые вы можете сделать с одним, присваивают ему значение, которое вы получаете из другого места, или передаете его на некоторый код, который ожидает IntPtr. IntPtr.Zero существует, чтобы разрешить один отсутствующий, но критически важный сценарий: нулевое значение. Вы не можете назначить ему 0
или протестировать его против 0
, и поскольку это не ссылка, вы не можете назначить или протестировать против null. Поэтому они создали его как специальную константу для представления "IntPtr, значение которого равно null".
Если вы хотите сделать эквивалент в Delphi, объявите указатель, а затем инициализируйте его нулем.
IntPtr
в Delphi является Pointer
(или NativeInt
в последних версиях, если вам нужно целое число), а эквивалентом IntPtr.Zero
в Delphi является nil
(или 0, если используется NativeInt
).
SAAT_Open()
). Проблема в другом месте, например, если вы неправильно инициализируетеpHandle
.