Problem marshalling CopyData structure for WM_COPYDATA message in x64(code works in x86)

Discussion in 'ASP .Net' started by d-42, May 5, 2008.

  1. d-42

    d-42 Guest

    Hi,

    I'm pretty sure I've just got a Marshalling problem, but I'm
    completely stumped. If there is a better newsgroup to post this in,
    please point me towards it.

    First I'm trying to use SendMessage() with WM_COPYDATA to send a
    string data between two instances of a program. As part of the
    debugging I've written two methods one where a given instance will
    obtain its own hWnd and send itself the message, one where it accepts
    obtains the hWnd of the other instance and sends it to the other one.
    Both methods work fine when compiled as x86. And the send-to-itself
    works on x64, but the send-to-another-instance breaks... the
    WM_COPYDATA message is sent, and received, but I'm unable to read back
    the string data.

    I *think* its a marshalling problem related to changes with x64. But
    I'm not sure.

    Here are the relevant bits:

    // The COPYDATA structure used for the WM_COPYDATA message:

    [StructLayout(LayoutKind.Sequential)]
    public struct COPYDATASTRUCT
    {
    [MarshalAs(UnmanagedType.U4)]
    public int dwData; // not used
    [MarshalAs(UnmanagedType.U4)]
    public int cbData; // holds length of string
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpData; //holds string
    }

    //DLL Import of SendMessage
    [DllImport("user32.dll", CharSet=CharSet.Ansi)]
    private static extern IntPtr SendMessage(IntPtr hWnd,
    [MarshalAs(UnmanagedType.U4)] int Msg,
    IntPtr wParam, ref COPYDATASTRUCT lParam);


    //The function that sends the message:

    public static IntPtr SendCopyDataMessage(IntPtr toHandle)
    {
    int messageid = 1234; // random message id

    stringdata = "Testing\0"; // send the string "Testing"

    // Create/populate the copydata structure.
    COPYDATASTRUCT dataStruct = new COPYDATASTRUCT();

    dataStruct.dwData = 0; //not used
    dataStruct.cbData = stringdata.Length;
    dataStruct.lpData = stringdata;

    // Make the call
    IntPtr result = SendMessage(toHandle, WM_COPYDATA,
    messageid, ref dataStruct);

    return result;
    }


    The WndProc that receives the messages is an override of Form.WndProc:

    // Process Custom Messages!
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == WM_COPYDATA)
    {
    // unpack the data
    string stringdata = ProcessWM_COPYDATA(m);
    // show what it was
    if (stringdata != null)
    {
    MessageBox.Show(stringdata);
    }
    }
    base.WndProc(ref m);
    }

    The function it calls to unpack the COPYDATA structure is as follows:

    public static string
    ProcessWM_COPYDATA(System.Windows.Forms.Message m)
    {
    if (m.WParam.ToInt32() == 1234)
    {
    COPYDATASTRUCT datastruct =
    (COPYDATASTRUCT)Marshal.PtrToStructure(
    m.LParam, typeof(COPYDATASTRUCT));
    return datastruct.lpData;
    }
    return null;
    }
    }

    As I said: It works when targeted at x86. In x64 it also works when I
    fire the send message at the same instance. (e.g. I have a button on
    the form that calls the SendCopyData(...) with its own window handle.

    The only time it doesn't work is when I have 2nd instance running and
    it calls SendCopyData(...) with the hWnd of the OTHER instance. In
    that case the message is received, and the MessageBox is displayed,
    but instead of saying testing its either blank or contains garbage
    data.

    I'd be grateful if someone can point out where I've screwed it up. As
    I said, I think its in marshalling/unmarshalling the lpData string,
    but I'm at a loss to fix it. I've tried doing it a number of ways,
    including setting lpData in COPYDATASTRUCTURE to an IntPtr, and then
    manually calling Marshal.StringToHGlobal(stringdata); and then when
    unpacking it, calling Marshal.PtrToString(lpData), but I end up with
    the same behaviour... breaking in x64.

    -best regards,
    Dave
     
    d-42, May 5, 2008
    #1
    1. Advertising

  2. d-42

    d-42 Guest

    Re: Problem marshalling CopyData structure for WM_COPYDATA message inx64 (code works in x86)

    >
    > I'm pretty sure I've just got a Marshalling problem, but I'm
    > completely stumped. If there is a better newsgroup to post this in,
    > please point me towards it.


    Aw crap. I didn't even post to the newsgroup I intended. Sorry about
    that.

    -Dave
     
    d-42, May 5, 2008
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Frank Bechmann
    Replies:
    0
    Views:
    429
    Frank Bechmann
    Jan 2, 2004
  2. Chris

    win32 problem with WM_COPYDATA

    Chris, Nov 26, 2004, in forum: Python
    Replies:
    3
    Views:
    607
    Neil Hodgson
    Nov 28, 2004
  3. Trent Mick
    Replies:
    0
    Views:
    420
    Trent Mick
    Jun 28, 2005
  4. Rory Becker

    x64 vs x86 vs AnyCPU

    Rory Becker, Mar 30, 2009, in forum: ASP .Net
    Replies:
    1
    Views:
    1,245
    Rory Becker
    Mar 30, 2009
  5. cybose
    Replies:
    2
    Views:
    97
    smallpond
    Dec 18, 2007
Loading...

Share This Page