While updating a third party library to work correctly on x64 (it’s using int for pointers), I was looking at the P/Invoke signatures.
One of them requires
__out LPSCARDCONTEXT phContext
This is defined in WinSCard.h
typedef ULONG_PTR SCARDCONTEXT;
typedef SCARDCONTEXT *PSCARDCONTEXT, *LPSCARDCONTEXT;
I’m not really familiar with C++, so correct me if I’m wrong. This means LPSCARDCONTEXT is a pointer to a ULONG_PTR, which is a pointer too. This also explains why IntPtr phContext doesn’t work and ref IntPtr phContext does work, in the P/Invoke signature.
I’m confused by the design. Why is a pointer to a pointer needed/used?
While I think @David Hefferman is absolutely right there’s a second part to the question which he did not address.
The part which he did not talk about is that pointers to pointers do exist as they are sometimes used to return pointers from function as arguments. Here’s a more detailed discussion about the benefits of pointers-to-pointers.
Also, the reason you need to use the
refkeyword in order to correctly marshal the data to-from your C# code is that unless you use ref, the data is only marshaled into the native code. If you need to receive the modified value into your argument (which is indicated by the fact that the variable is declared as a pointer) then you need to usereforoutto indicate to the P/Invoke API that you need the data marshaled out of the native code after the function is done executing.