Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make IntPtr in C#.NET point to string value

Tags:

I am using a class which has StringHandle field which is an IntPtr value that represents a LPCWSTR in C++.

internal IntPtr StringHandle; // LPCWSTR

say now that I have a String: string x = "abcdefg"

How can I use the String handle to point to the beginning of the String so that it is like C++ LPCWSTR ?

like image 361
Saher Ahwal Avatar asked Jun 18 '12 20:06

Saher Ahwal


People also ask

How to dereference IntPtr in c#?

In order to dereference an IntPtr , you can either cast it to a true pointer (an operation which can only be performed in "unsafe" contexts) or you can pass it to a helper routine such as those provided by the InteropServices. Marshal class.

How to use IntPtr in c#?

You can use IntPtr objects this way: int test = 55; // Allocating memory for int IntPtr intPointer = Marshal. AllocHGlobal(sizeof(int)); Marshal. WriteInt32(intPointer,test); // sending intPointer to unmanaged code here //Test reading of IntPtr object int test2 = Marshal.

What IntPtr?

The IntPtr type is designed to be an integer whose size is the same as a pointer. That is, an instance of this type is expected to be 32 bits in a 32-bit process and 64 bits in a 64-bit process.

What IntPtr zero?

IntPtr. Zero is just a constant value that represents a null pointer.


2 Answers

You need to copy the string to the unmanaged memory first and then get the IntPtr from that location. You can do so like:

IntPtr strPtr = Marshal.StringToHGlobalUni(x);

also, you need to make sure to free the unmanaged memory:

Marshal.FreeHGlobal(strPtr);

it's best to do all this in a try/finally.

like image 155
Eren Ersönmez Avatar answered Sep 18 '22 09:09

Eren Ersönmez


Managed strings move in memory when the garbage collector compacts the heap. So they don't have a stable address and can't directly be cast to a LPCWSTR. You'll need to either pin the string with GCHandle.Alloc() to use GCHandle.AddrOfPinnedObject or copy it into unmanaged memory with Marshal.StringToHGlobalUni().

Strongly prefer copying if the address needs to be stable for a while.

like image 29
Hans Passant Avatar answered Sep 20 '22 09:09

Hans Passant