By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,369 Members | 1,188 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,369 IT Pros & Developers. It's quick & easy.

Mashalling IntPtr into a byte array? I can see how to do it the other way around!

P: n/a

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL)
into a byte array. I know the size of the array required and I've got a
pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not
blittable! (byte is a blittable type however). Cannot use Marshal.Copy,
because that works the other way around (for mashalling to COM, not from
it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try
Nov 20 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Hi,

Did you try Marshal.PtrToStructure?

Ken
------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL)
into a byte array. I know the size of the array required and I've got a
pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not
blittable! (byte is a blittable type however). Cannot use Marshal.Copy,
because that works the other way around (for mashalling to COM, not from
it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try

Nov 20 '05 #2

P: n/a
Yes, that was my first attempt, I wrote:

Marshal.PtrToStructure( myAudioPtr, theSoundByteArray)

Exception was: "The specified structure must be blittable or have layout
information."

I was under the impression that byte was blittable, as was the complex type
byte()?
"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:eU*************@TK2MSFTNGP10.phx.gbl...
Hi,

Did you try Marshal.PtrToStructure?

Ken
------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL) into a byte array. I know the size of the array required and I've got a
pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not
blittable! (byte is a blittable type however). Cannot use Marshal.Copy,
because that works the other way around (for mashalling to COM, not from
it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try


Nov 20 '05 #3

P: n/a
I got it:

theLocked is my locked HGLOBAL

Sound is byte(theAudioSize)

then,

Marshal.Copy(theLocked, Sound, 0, theAudioSize)

"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...
Yes, that was my first attempt, I wrote:

Marshal.PtrToStructure( myAudioPtr, theSoundByteArray)

Exception was: "The specified structure must be blittable or have layout
information."

I was under the impression that byte was blittable, as was the complex type byte()?
"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:eU*************@TK2MSFTNGP10.phx.gbl...
Hi,

Did you try Marshal.PtrToStructure?

Ken
------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL) into a byte array. I know the size of the array required and I've got a pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not blittable! (byte is a blittable type however). Cannot use Marshal.Copy, because that works the other way around (for mashalling to COM, not from it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try



Nov 20 '05 #4

P: n/a
Hi,

I guess I should have read your message better. When I use the
netserverenum api it returns a pointer to an array. I have to read each
element of the array individually. Here is an example. I hope this helps.

Imports System.Runtime.InteropServices

Module Module1

Structure Computer_info_101

Public Platform_ID As Integer

<MarshalAsAttribute(UnmanagedType.LPWStr)> Public Name As String

Public Version_Major As Integer

Public Version_Minor As Integer

Public Type As Integer

<MarshalAsAttribute(UnmanagedType.LPWStr)> Public Comment As String

End Structure

Declare Unicode Function NetServerEnum Lib "Netapi32.dll" _

(ByVal Servername As Integer, ByVal level As Integer, _

ByRef buffer As Integer, ByVal PrefMaxLen As Integer, _

ByRef EntriesRead As Integer, ByRef TotalEntries As Integer, _

ByVal ServerType As Integer, ByVal DomainName As String, _

ByRef ResumeHandle As Integer) As Integer

Declare Function NetApiBufferFree Lib "Netapi32.dll" _

(ByVal lpBuffer As Integer) As Integer

Private Const SV_TYPE_SERVER As Integer = &H2 ' All Servers

Sub Main()

Dim ComputerInfo As Computer_info_101

Dim i, MaxLenPref, level, ret, EntriesRead, TotalEntries, ResumeHandle As
Integer

Dim BufPtr As Integer

Dim iPtr As IntPtr

MaxLenPref = -1

level = 101

ret = NetServerEnum(0, level, BufPtr, MaxLenPref, EntriesRead, TotalEntries,
_

SV_TYPE_SERVER, "MSHOME", ResumeHandle) ' Replace MSHOME with your workgroup
name

If ret <> 0 Then

Console.WriteLine("An Error has occured")

Return

End If

' loop thru the entries

For i = 0 To EntriesRead - 1

' copy the stuff into our structure

Dim ptr As IntPtr = New IntPtr(BufPtr)

computerInfo = CType(Marshal.PtrToStructure(ptr,
GetType(Computer_info_101)), _

Computer_info_101)

BufPtr = BufPtr + Len(ComputerInfo)

Console.WriteLine(computerInfo.Name)

Next

NetApiBufferFree(BufPtr)

Console.Write("Press Enter to End")

Dim s As String = Console.ReadLine()

End Sub

End Module

Ken
--------------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...
Yes, that was my first attempt, I wrote:

Marshal.PtrToStructure( myAudioPtr, theSoundByteArray)

Exception was: "The specified structure must be blittable or have layout
information."

I was under the impression that byte was blittable, as was the complex type byte()?
"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:eU*************@TK2MSFTNGP10.phx.gbl...
Hi,

Did you try Marshal.PtrToStructure?

Ken
------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL) into a byte array. I know the size of the array required and I've got a pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not blittable! (byte is a blittable type however). Cannot use Marshal.Copy, because that works the other way around (for mashalling to COM, not from it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try



Nov 20 '05 #5

P: n/a
Robin,
In addition to Ken's other comments.

My understanding is that Marshal.PtrToStructure & Mashal.StructureToPtr are
used for COMPLEX types. COMPLEX Types as in Structures & Classes. Remember
that Byte is blittable, as its a primitive type. Primitive type as in its
native to the machine, the managed & unmanaged representation are the same
(a 32bit unmanaged int has the same physical layout as a 32bit managed int).
My understanding is you need to use Marshal.Copy to copy arrays of primitive
types.

There are overloaded Marshal.Copy functions that copy from a byte array to
an IntPtr and that copy from an IntPtr to a Byte array. Watch your source &
destination arguments and you should be fine.

Dim theLocked As IntPtr
Dim theSound As System.Byte()
Dim theSoundSize as Integer
' Copy from HGLOBAL to the byte array
Marshal.Copy(theLocked, theSound, 0, theSoundSize)

' Copy from the byte array to HGLOBAL
Marshal.Copy(theSound, 0, theLocked, theSoundSize)

With Marshal.Copy the source is the first parameter, followed by the
destination. (Note arrays have 2 actual parameters, the array & the starting
index).

Adam Nathan's book ".NET and COM - The Complete Interoperability Guide" from
SAMS Press, provides you will every thing you ever wanted to know about
Interop and then some.

Hope this helps
Jay

"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...
Yes, that was my first attempt, I wrote:

Marshal.PtrToStructure( myAudioPtr, theSoundByteArray)

Exception was: "The specified structure must be blittable or have layout
information."

I was under the impression that byte was blittable, as was the complex type byte()?
"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:eU*************@TK2MSFTNGP10.phx.gbl...
Hi,

Did you try Marshal.PtrToStructure?

Ken
------------------------
"Robin Tucker" <id*************************@reallyidont.com> wrote in
message news:bn*******************@news.demon.co.uk...

I need to marshal an IntPtr (which I've got from GlobalLock of an HGLOBAL) into a byte array. I know the size of the array required and I've got a pointer to the blob, but I can't see how to copy the memory across.

Using Marshal.PtrStructure doesn't work - it says my byte() array is not blittable! (byte is a blittable type however). Cannot use Marshal.Copy, because that works the other way around (for mashalling to COM, not from it).

Any ideas?

Dim theLocked As IntPtr
Try

' Find out how big the HGLOBAL allocation returned is

Dim theAudioSize As Integer = GlobalSize(hAudio)

' an array to store the WAV

Dim theSound As System.Byte()

' Resize the array

ReDim theSound(theAudioSize)

' Now, lock its buffer so we can load it in to our variable.

theLocked = GlobalLock(hAudio)

' Marshal "theLocked" into the array

??????????????????????

Catch Ex As Exception

' Whoops

Finally
Marshal.FreeHGlobal(theLocked)
End Try



Nov 20 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.