Home All Groups Group Topic Archive Search About
Author
2 Jul 2009 2:53 AM
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));
        }
    }
}

Author
2 Jul 2009 6:15 AM
Tim Roberts
clawton <claw***@discussions.microsoft.com> wrote:
..>
>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;
--
Tim Roberts, t***@probo.com
Providenza & Boekelheide, Inc.
Are all your drivers up to date? click for free checkup

Author
2 Jul 2009 10:44 PM
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


Show quoteHide quote
"Tim Roberts" wrote:

> clawton <claw***@discussions.microsoft.com> wrote:
> ..>
> >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;
> --
> Tim Roberts, t***@probo.com
> Providenza & Boekelheide, Inc.
>

Bookmark and Share