Unsafe code: Converting "byte *" to "[] byte"

B

_BNC

I've converted "[] byte" to "byte *" at times, using 'unsafe' and
fixed { .... }, but the reverse does not seem to work.

In this case, a C++ DLL returns a byte * and a length. What is the best
way to convert these to straight C#-compatible straight "[] byte" arrays?

PS: The C++ DLL is actually managed and I have access to the source.
Perhaps there is a simpler syntax for doing the conversion there, and
returning a C# compatible array rather than a pointer?
 
B

Bob Powell [MVP]

You'll need to create a byte array and copy the contents of the pointer to
it.

The Marshal class will enable you to do this.

byte[] bytes=new byte[length];
for(int i=0; i<length; i++)
bytes=Marshal.ReadByte(fromPointer,i);

bytes now contains the copy of the memory pointed to by fromPointer.

Marshal.Copy goes the other way, from the byte array to the pointer. Shame
they couldn't have written a copyfrom method.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
W

Willy Denoyette [MVP]

Bob Powell said:
You'll need to create a byte array and copy the contents of the pointer to
it.

The Marshal class will enable you to do this.

byte[] bytes=new byte[length];
for(int i=0; i<length; i++)
bytes=Marshal.ReadByte(fromPointer,i);

bytes now contains the copy of the memory pointed to by fromPointer.

Marshal.Copy goes the other way, from the byte array to the pointer. Shame
they couldn't have written a copyfrom method.


This has been taken care of in v2.0 using an overload of Marshal.Copy.

Willy.
 
B

_BNC

[re turning 'byte *' into C# '[] byte'

Bob Powell said:
You'll need to create a byte array and copy the contents of the pointer to
it.

The Marshal class will enable you to do this.

byte[] bytes=new byte[length];
for(int i=0; i<length; i++)
bytes=Marshal.ReadByte(fromPointer,i);

bytes now contains the copy of the memory pointed to by fromPointer.

Marshal.Copy goes the other way, from the byte array to the pointer. Shame
they couldn't have written a copyfrom method.


This has been taken care of in v2.0 using an overload of Marshal.Copy.

Willy.


The horror. Runtime is bad enough already. Is there no way to do this
without copying bytes? I'm going through both an unmanaged C++ layer and
then a managed C++ layer before it gets to C#. Is there a simple way to
cast this somewhere in the C++ layers?

I'm also not sure why I'd have to use 'Marshall' to copy the array. If
I've already got a pointer and length, I could just do the copy directly,
right? OK, I'm probably being dense.
 
W

Willy Denoyette [MVP]

_BNC said:
[re turning 'byte *' into C# '[] byte'

Bob Powell said:
You'll need to create a byte array and copy the contents of the pointer
to
it.

The Marshal class will enable you to do this.

byte[] bytes=new byte[length];
for(int i=0; i<length; i++)
bytes=Marshal.ReadByte(fromPointer,i);

bytes now contains the copy of the memory pointed to by fromPointer.

Marshal.Copy goes the other way, from the byte array to the pointer.
Shame
they couldn't have written a copyfrom method.


This has been taken care of in v2.0 using an overload of Marshal.Copy.

Willy.


The horror. Runtime is bad enough already. Is there no way to do this
without copying bytes? I'm going through both an unmanaged C++ layer and
then a managed C++ layer before it gets to C#. Is there a simple way to
cast this somewhere in the C++ layers?

I'm also not sure why I'd have to use 'Marshall' to copy the array. If
I've already got a pointer and length, I could just do the copy directly,
right? OK, I'm probably being dense.


There's no need to copy when passing managed types between C# and Managed
C++. You only should copy from managed to unmanaged memory and the other way
arround.

Willy.
 
G

Guest

I have a similar situation. C# application, unmanaged com object
(directshow filter). Using a callback function I would like to get a copy of
the data that filter has.

I've been trying:

//COM
typedef HRESULT (* MYCALLBACK) ( IMediaSample *pSample, long lSize );
HRESULT MyClass::Transform(IMediaSample *pMediaSample)
{
CheckPointer(pMediaSample,E_POINTER);
if(m_callback)
{
m_callback(pDestBuffer, lSourceSize);
}
return S_OK;
}

//C#
public delegate void CallBackDelegate(IntPtr pSample, int dataLength);
public void CallbackFunction(IntPtr pSample, int dataLength)
{
byte [] buffer = new byte [dataLength];
Marshal.Copy(pSample,buffer,0,dataLength);
}

It crashes on the Marshal.Copy. Any suggestions on how to accomplish this?
I have the source for both the managed and unmanaged sides so I can change
both if necessay.


Willy Denoyette said:
_BNC said:
[re turning 'byte *' into C# '[] byte'

You'll need to create a byte array and copy the contents of the pointer
to
it.

The Marshal class will enable you to do this.

byte[] bytes=new byte[length];
for(int i=0; i<length; i++)
bytes=Marshal.ReadByte(fromPointer,i);

bytes now contains the copy of the memory pointed to by fromPointer.

Marshal.Copy goes the other way, from the byte array to the pointer.
Shame
they couldn't have written a copyfrom method.


This has been taken care of in v2.0 using an overload of Marshal.Copy.

Willy.


The horror. Runtime is bad enough already. Is there no way to do this
without copying bytes? I'm going through both an unmanaged C++ layer and
then a managed C++ layer before it gets to C#. Is there a simple way to
cast this somewhere in the C++ layers?

I'm also not sure why I'd have to use 'Marshall' to copy the array. If
I've already got a pointer and length, I could just do the copy directly,
right? OK, I'm probably being dense.


There's no need to copy when passing managed types between C# and Managed
C++. You only should copy from managed to unmanaged memory and the other way
arround.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top