Reputation: 273
After some research I translated
pHandle = IntPtr.Zero;
to Delphi
var
pHandle: Pointer;
When I break for debug in Delphi I get $314328
, when I break for debug on C sharp I get an Integer value 134180640
. Can anyone tell me how to make the correct translation to Delphi?
The Dll function that I am calling in Delphi is:
function SAAT_Open(pHandle: Pointer): Boolean; stdcall;
The C sharp Function is:
[DllImport("RFIDAPI.dll", EntryPoint = "SAAT_Open")]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool SAAT_Open(IntPtr pHandle);
Upvotes: 1
Views: 1905
Reputation: 612794
After some research I translated
pHandle = IntPtr.Zero;
to Delphi
var pHandle: Pointer;
Can anyone tell me how to make the correct translation to Delphi?
C# syntax allows you to initialize a variable in the same statement that you declare the variable:
IntPtr Handle = IntPtr.Zero;
In Delphi you cannot initialize a local variable as you declare it. So you need to declare it, and then initialize it:
var
Handle: Pointer;
....
Handle := nil;
Until you assign to a local variable, of an unmanaged type, its value is undefined.
However, if you pass nil
to SAAT_Open
then it will fail. The function expects a non null handle. So, initializing to nil
won't help you. You need to do more. You need to call the function that yields a new handle. That is SAAT_TCPInit
. The C# code that you show, that initializes the handle to a null value, does so needlessly. Perhaps it does so because the SAAT_TCPInit
was erroneously translated to use a ref
parameter for the handle, rather than the correct translation which would be an out
parameter.
Whilst the above answers the question you asked, it won't help solve your problem. You don't need a null handle, you need an actual handle.
When I break for debug in Delphi I get $314328, when I break for debug on C sharp I get an Integer value 134180640.
Well, after pHandle = IntPtr.Zero
you absolutely will not see the value 134180640
in C#. You will see the value 0
. There must be some other code that initializes the handle. Presumably a call to SAAT_TCPInit
. You do need to make that call. I trust that you are doing so.
The handle will not necessarily have the same value on subsequent executions of your program. And need not have the same value in each different program. The handle is actually a dynamically allocated pointer and its address is variable from one run to the next. So it is nothing to worry about if it varies as you have observed. If SAAT_TCPInit
returns True
to indicate success, then the handle value will be valid.
Upvotes: 2
Reputation: 84540
In .NET, IntPtr is a representation of a pointer type that is implemented under the hood by an integer, because it can't be an actual .NET pointer (reference), because "real" references have to be managed. But it can't be a real integer either, or you might do math on it, which is a good way to get memory corruption. (NOTE: This restriction may or may not exist, depending on which version of C# and/or the CLR you're using.)
But since you can't treat an IntPtr as an integer, the only useful things you can do with one are assign it a value you get from elsewhere, or pass it to some code that expects an IntPtr. IntPtr.Zero exists to resolve one missing but critically important scenario: the null value. You can't assign 0
to it or test it against 0
, and since it's not a reference, you can't assign or test against null. So they created it as a special constant to represent "IntPtr whose value is null."
If you want to do the equivalent in Delphi, declare the pointer and then initialize it to nil.
Upvotes: 3