Marshal.Copy

C

clawton

Hi All,

With the simple code below I get an exception on the last line of code...
Just trying to figure out some marshalling stuff...but I'm stuck...
Ultimately, the source pointer is data created in a DLL called by p/Invoke
and I need to get the data out of it into some structs.

Any help pointing out what I'm doing wrong here would be greatly appriciated!
Thanks in advance!
Chris

----------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace CopyTest
{
class Program
{
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct foo
{
public int x;
public double y;
};


static void Main(string[] args)
{


foo f = new foo();
f.x = 217;
f.y = -999.0;


IntPtr srcptr = Marshal.AllocHGlobal(Marshal.SizeOf(f));
Marshal.StructureToPtr(f, srcptr, true);

IntPtr[] one = new IntPtr[1];

Marshal.Copy(srcptr, one, 0, 1);

foo dest = (foo)Marshal.PtrToStructure(one[0], typeof(foo));
}
}
}
 
T

Tim Roberts

clawton said:
With the simple code below I get an exception on the last line of code...
Just trying to figure out some marshalling stuff...but I'm stuck...
Ultimately, the source pointer is data created in a DLL called by p/Invoke
and I need to get the data out of it into some structs.

Any help pointing out what I'm doing wrong here would be greatly appriciated!

Your problem is actually in the Marshal.Copy.
IntPtr srcptr = Marshal.AllocHGlobal(Marshal.SizeOf(f));
Marshal.StructureToPtr(f, srcptr, true);

IntPtr[] one = new IntPtr[1];

Marshal.Copy(srcptr, one, 0, 1);

That doesn't do what you think it does. What it actually does is copy 4
bytes from the memory that srcptr POINTS TO, not the CONTENTS of srcptr.
This would have been obvious if you had done a minimum of debugging:

System.Console.WriteLine( srcptr );
System.Console.WriteLine( one[0] );

You would see that srcptr contains an address, but one[0] contains 217,
which happens to be the value you initialized into foo.x.

In this case, you would just do this instead:
one[0] = srcptr;
 
C

clawton

Yeah, I figured it out a few minutes after I posted!
For some reason, I got it stuck in my head that it should be the contents
and just couldn't get past it...argh... :(

Thanks for the reply.
Chris


Tim Roberts said:
clawton said:
With the simple code below I get an exception on the last line of code...
Just trying to figure out some marshalling stuff...but I'm stuck...
Ultimately, the source pointer is data created in a DLL called by p/Invoke
and I need to get the data out of it into some structs.

Any help pointing out what I'm doing wrong here would be greatly appriciated!

Your problem is actually in the Marshal.Copy.
IntPtr srcptr = Marshal.AllocHGlobal(Marshal.SizeOf(f));
Marshal.StructureToPtr(f, srcptr, true);

IntPtr[] one = new IntPtr[1];

Marshal.Copy(srcptr, one, 0, 1);

That doesn't do what you think it does. What it actually does is copy 4
bytes from the memory that srcptr POINTS TO, not the CONTENTS of srcptr.
This would have been obvious if you had done a minimum of debugging:

System.Console.WriteLine( srcptr );
System.Console.WriteLine( one[0] );

You would see that srcptr contains an address, but one[0] contains 217,
which happens to be the value you initialized into foo.x.

In this case, you would just do this instead:
one[0] = srcptr;
 

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