Discussion:
getting a c# byte array to unmanaged memory (without copying)
(too old to reply)
nickdu
2009-03-03 15:33:01 UTC
Permalink
I'm trying to use shared memory within my c# application. I'm using .NET 2.0
so if there are shared memory functions added post 2.0 I can't use them.

The unmanaged API I'm trying to view as a byte[] is MapViewOfFile(). Is
there a way to get the void * returned from MapViewOfFile() to be a c# byte[]
without copying the data? Do I need to inject some managed C++ in order to
get this to work, if it's even possible?
--
Thanks,
Nick

***@community.nospam
remove "nospam" change community. to msn.com
Jeroen Mostert
2009-03-03 18:24:37 UTC
Permalink
Post by nickdu
I'm trying to use shared memory within my c# application. I'm using .NET 2.0
so if there are shared memory functions added post 2.0 I can't use them.
The unmanaged API I'm trying to view as a byte[] is MapViewOfFile(). Is
there a way to get the void * returned from MapViewOfFile() to be a c# byte[]
without copying the data?
No. This just isn't possible. You can work with the void* in C# just fine,
if you mark your code as unsafe, but you have to treat it for what it is: a
pointer. You can pin a managed array and directly access its contents as a
pointer, but you can't make the runtime treat a pointer as a managed array
because it's strictly more than a pointer. You'll have to settle on some
strategy to minimize copying, but you can't eliminate it entirely unless you
write all code involving the shared memory as unsafe (or just write it in
unmanaged code to begin with, which would probably be easier).
--
J.
Jialiang Ge [MSFT]
2009-03-04 10:02:21 UTC
Permalink
I second J and Nick's idea of using C++ / CLI.

Here I list J and Nick's ideas and give a small supplement:

S 1. Copy data (unwanted because of the use of memory.)

S 2. Write unsafe code in C# to directly access the native memory.
For example,
IntPtr pBuffer = MapViewOfFile(hHandle, FILE_MAP_ALL_ACCESS, 0, 0,
NumBytes);
byte* rawPointer = (byte*)p.ToPointer();

S 3. Writing C++/CLI or managed C++.

S 4. Wrap the use of memory map in a native C++ DLL, and P/Invoke the
native DLL from C# client.

S 5. Without the use of "unsafe" code, Marshal.ReadByte and
Marshal.WriteByte can also be an option. Both methods accept the parameter
of IntPtr, and the offset from the address, so that we can read from or
write to the specified position.

Regards,
Jialiang Ge (***@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
tom@vandeplas.com
2009-03-17 08:27:01 UTC
Permalink
Did you consider System.IO.UnmanagedMemoryStream ? Don't forget to set the
CanWrite and CanRead properties...

Regards, Tom

Loading...