473,785 Members | 2,298 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

(apparent) Marshalling related problem in x64 but works in x86

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(La youtKind.Sequen tial)]
public struct COPYDATASTRUCT
{
[MarshalAs(Unman agedType.U4)]
public int dwData; // not used
[MarshalAs(Unman agedType.U4)]
public int cbData; // holds length of string
[MarshalAs(Unman agedType.LPStr)]
public string lpData; //holds string
}

//DLL Import of SendMessage
[DllImport("user 32.dll", CharSet=CharSet .Ansi)]
private static extern IntPtr SendMessage(Int Ptr hWnd,
[MarshalAs(Unman agedType.U4)] int Msg,
IntPtr wParam, ref COPYDATASTRUCT lParam);

//The function that sends the message:

public static IntPtr SendCopyDataMes sage(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.dwDa ta = 0; //not used
dataStruct.cbDa ta = stringdata.Leng th;
dataStruct.lpDa ta = stringdata;

// Make the call
IntPtr result = SendMessage(toH andle, 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_COPYD ATA(m);
// show what it was
if (stringdata != null)
{
MessageBox.Show (stringdata);
}
}
base.WndProc(re f m);
}

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

public static string
ProcessWM_COPYD ATA(System.Wind ows.Forms.Messa ge m)
{
if (m.WParam.ToInt 32() == 1234)
{
COPYDATASTRUCT datastruct =
(COPYDATASTRUCT )Marshal.PtrToS tructure(
m.LParam, typeof(COPYDATA STRUCT));
return datastruct.lpDa ta;
}
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 COPYDATASTRUCTU RE to an IntPtr, and then
manually calling Marshal.StringT oHGlobal(string data); and then when
unpacking it, calling Marshal.PtrToSt ring(lpData), but I end up with
the same behaviour... breaking in x64.

-best regards,
Dave
Jun 27 '08 #1
2 2149
The dwData member of COPYDATASTRUCT is not an int. It is a pointer sized
type so you must use IntPtr in your struct definition.
"d-42" <db********@gma il.comwrote in message
news:e3******** *************** ***********@v26 g2000prm.google groups.com...
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(La youtKind.Sequen tial)]
public struct COPYDATASTRUCT
{
[MarshalAs(Unman agedType.U4)]
public int dwData; // not used
[MarshalAs(Unman agedType.U4)]
public int cbData; // holds length of string
[MarshalAs(Unman agedType.LPStr)]
public string lpData; //holds string
}

//DLL Import of SendMessage
[DllImport("user 32.dll", CharSet=CharSet .Ansi)]
private static extern IntPtr SendMessage(Int Ptr hWnd,
[MarshalAs(Unman agedType.U4)] int Msg,
IntPtr wParam, ref COPYDATASTRUCT lParam);

//The function that sends the message:

public static IntPtr SendCopyDataMes sage(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.dwDa ta = 0; //not used
dataStruct.cbDa ta = stringdata.Leng th;
dataStruct.lpDa ta = stringdata;

// Make the call
IntPtr result = SendMessage(toH andle, 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_COPYD ATA(m);
// show what it was
if (stringdata != null)
{
MessageBox.Show (stringdata);
}
}
base.WndProc(re f m);
}

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

public static string
ProcessWM_COPYD ATA(System.Wind ows.Forms.Messa ge m)
{
if (m.WParam.ToInt 32() == 1234)
{
COPYDATASTRUCT datastruct =
(COPYDATASTRUCT )Marshal.PtrToS tructure(
m.LParam, typeof(COPYDATA STRUCT));
return datastruct.lpDa ta;
}
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 COPYDATASTRUCTU RE to an IntPtr, and then
manually calling Marshal.StringT oHGlobal(string data); and then when
unpacking it, calling Marshal.PtrToSt ring(lpData), but I end up with
the same behaviour... breaking in x64.

-best regards,
Dave

Jun 27 '08 #2
Thank you very much, that resolved the problem.

-regards,
Dave
On May 5, 7:21 am, "Stephen Martin"
<smar...@remove this.emsoft.and this.cawrote:
The dwData member of COPYDATASTRUCT is not an int. It is a pointer sized
type so you must use IntPtr in your struct definition.
Jun 27 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2867
by: Animesh | last post by:
Hi All, I don't know whethher this is possible or not. This is the result of a bad design problem. Here I go; I have a structure like this: typedef struct _s_index_entry { char *doc_id; double s_id;
7
606
by: GianPiero Andreis | last post by:
Hello All, let me pose a simple question about combobox and the CB_INSERTSTRING message. Suppose for instance that I already have a combobox handle, how can I declare and use the SendMessage function just for insert a new item into the combobox ? Of course, the combo box DO NOT belong to my process, so I can't use the standard properties of that class. In fact, I need to "put" a new entry in the combo box of IExplorer. EnumWindows get...
2
5551
by: Howard Kaikow | last post by:
I've got the following in a VB 6 project: Private Type PROCESSENTRY32 dwSize As Long cntUsage As Long th32ProcessID As Long th32DefaultHeapID As Long th32ModuleID As Long cntThreads As Long th32ParentProcessID As Long
0
1147
by: swartzbill2000 | last post by:
I am familiar with the VB6/VC6/ATL way of marshalling an incoming interface via New (VB), and then marshalling an outgoing interface with some form of Advise. To me it looks like .Net has marshalling on a function-by-function basis. Is there a way in .Net to marshall entire interfaces? Bill
2
1423
by: bonk | last post by:
I am currently trying to write a longer article about Marshalling when using . Does anyone know books, articles, or websites that cover Marshalling in Platform Invocation Services ()?
10
2550
by: Bryce Calhoun | last post by:
Hello, First of all, this is a .NET 1.1 component I'm creating. SUMMARY ----------------------- This component that I'm creating is, for all intents and purposes, a document parser (I'm actually deserializing a SOAP document into an object and parsing out the fields, but that's fairly immaterial to this
2
2491
by: RJ Lohan | last post by:
Howdy, I have a legacy DLL for which I have a problem marshalling a parameter type of char**. The function header (C++) is as so; extern "C" __declspec(dllexport) int __stdcall GetChildren(GetChildrenParm *, Results *);
2
3353
by: calenlas | last post by:
Hi all, I'm taking my first steps into C# <--C++ DLL Interop and unfortunately I've run into (what seems to be) a very complicated case as my first task. Perhaps someone here can help me. I need to pass an array of RADIO_INFO2 structures to be filled by a function in the DLL. This is how the structure is defined in the C++ example that comes with the DLL:
1
2551
by: d-42 | last post by:
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
0
10341
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10095
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9954
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7502
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6741
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5383
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5513
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4054
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2881
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.