Re: String to byte[] reloaded
- From: "Ben Voigt" <rbv@xxxxxxxxxxxxx>
- Date: Mon, 12 Feb 2007 19:01:04 -0600
"nano2k" <adrian.rotaru@xxxxxxxxxxx> wrote in message
news:1171270149.638283.256770@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi, thanks all for your replys.
I will answer to some ideas in this one place.
Indeed, most of them don't allocate, but relies on you to allocate.
So, in my perspective, it's the same.
I am using .NET framework v1.1 and I need to compress my string.
Unfortunately, the compressing library (no sources available to me)
takes an byte[] as input parameter and I have a string to compress.
It is frustrating that I have to allocate new memory to perform this
operation. This sometimes leads to webservice crash, as many requests
simultaneously require this operation => not enough memory.
I do not intend to use the buffer but for strict readonly operations.
I am aware that any "unmanaged" changes in such an intimate buffer
could cause future unexpected behavior.
Here's your loaded gun, plenty of rope to hang yourself (I looked at the
C++/CLI function PtrToStringChars):
string s = "This is a test string";
GCHandle ptr = GCHandle.Alloc(s);
byte* pString = *(byte**)GCHandle.ToIntPtr(ptr).ToPointer() +
System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData;
char* c = (char*)pString;
ptr.Free();
GCHandle pinptr = GCHandle.Alloc(s, GCHandleType.Pinned);
pString = (byte*)pinptr.AddrOfPinnedObject().ToPointer();
c = (char*)pString;
pinptr.Free();
Note that the Large Object Heap is a heap, and not subject to garbage
collection, in which case you ought not need to pin the object.
BTW, that OffsetToStringData is 12 (at least in .NET 2.0) but it's a real
property, not a constant, so the value is gotten from your actual runtime
library, not when you compile. Of course the JIT will inline that property
access to nothing anyway.
The PtrToStringChars code is the same in both .NET 1.1 and 2.0, so this
might be almost stable.
I don't know why the offset isn't needed when you use a pinning pointer. I
did notice that the pinning action moves the string though... let me try
with a larger string....
With a one million character string, there is no change in the pointer, and
the AddrOfPinnedObject call still includes the correct offset. Probably
small objects get moved to the Large Object Heap in order to pin them (and
do they come back, maybe once pinned, always pinned until all references
disappear?).
So that's how to get a zero-copy pointer to the internal data of a large
string.
Note that everything here is based on my quick tests and reading vcclr.h and
I may just have gotten lucky; pressure on the GC could move things around
and mess things up, or other bad things could happen.
.
- Follow-Ups:
- Re: String to byte[] reloaded
- From: Willy Denoyette [MVP]
- Re: String to byte[] reloaded
- From: nano2k
- Re: String to byte[] reloaded
- From: Jon Skeet [C# MVP]
- Re: String to byte[] reloaded
- References:
- String to byte[] reloaded
- From: nano2k
- Re: String to byte[] reloaded
- From: Barry Kelly
- Re: String to byte[] reloaded
- From: nano2k
- String to byte[] reloaded
- Prev by Date: Worker thread preventing application shutdown
- Next by Date: Set message subject here ...
- Previous by thread: Re: String to byte[] reloaded
- Next by thread: Re: String to byte[] reloaded
- Index(es):
Relevant Pages
|