Help with COPYDATASTRUCT in C# Windows Mobile 5.0

N

New Bee

I have a C++ app that is sending the following data to a C# app through WM_COPYDATA
message. The below is the custom structre that I am sending.


C++ code:
========
struct sData
{

private:
int id;
char szData[1024];

public:
sData()
{
memset(this, NULL, sizeof(sData));
}

public:
void SetData(int iApp, char* pszData)
{
id = iApp;
strcpy(szData, pszData);
}
};

sData data;

data.SetData(1, "Hello! from Native code.");

COPYDATASTRUCT ds;
ds.dwData = (WPARAM)0;
ds.cbData = sizeof(sData);

ds.lpData = &data;

r = SendMessage(hCWnd, WM_COPYDATA, (WPARAM)0, (LPARAM)&ds);


C# code:
=======

struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}

struct Data
{
public int id;
public string buf;
}

In a class that implements MessageWindow.

protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT ds = (COPYDATASTRUCT)Marshal.PtrToStructure(msg.LParam,
typeof(COPYDATASTRUCT));

Data data = (Data)Marshal.PtrToStructure(ds.lpData, typeof(Data));
// <<--- Give me unsupported error
}
......
......
.....
 
G

Guest

The problem is in your Data structure. The marshaler is choking on the public
string buf member.
 
N

New Bee

Hello Alex Yakhnin [MVP],

Thank you. Please tell me the type of the buf below and how can I access
it from my c# code.

struct PimData
{
public int id;
public string buf; // <-- this is declared in C++ as char 1024.
should it be TCHAR ?
}

I am new to this interop and has no clue. I have looked at various previous
posts and most of them talk about passing a string but not a custom structure
from c++.

Regards.
The problem is in your Data structure. The marshaler is choking on the
public string buf member.

--
Alex Yakhnin, .NET CF MVP
www.intelliprog.com | www.opennetcf.org
New Bee said:
I have a C++ app that is sending the following data to a C# app
through WM_COPYDATA message. The below is the custom structre that I
am sending.

C++ code:
========
struct sData
{
private:
int id;
char szData[1024];
public:
sData()
{
memset(this, NULL, sizeof(sData));
}
public:
void SetData(int iApp, char* pszData)
{
id = iApp;
strcpy(szData, pszData);
}
};
sData data;

data.SetData(1, "Hello! from Native code.");

COPYDATASTRUCT ds;
ds.dwData = (WPARAM)0;
ds.cbData = sizeof(sData);
ds.lpData = &data;

r = SendMessage(hCWnd, WM_COPYDATA, (WPARAM)0, (LPARAM)&ds);

C# code:
=======
struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}
struct Data
{
public int id;
public string buf;
}
In a class that implements MessageWindow.

protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT ds =
(COPYDATASTRUCT)Marshal.PtrToStructure(msg.LParam,
typeof(COPYDATASTRUCT));
Data data = (Data)Marshal.PtrToStructure(ds.lpData, typeof(Data));
// <<--- Give me unsupported error
}
......
......
......
 
N

New Bee

Thanks everybody.

I got it this time. Changed my structure to this.

[StructLayout(LayoutKind.Sequential)]
struct Data
{
public int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string buf;
}

Also changed my C++ code from

char szData[1024];

to
TCHAR szPimData[1024];

Everything works fine now.

Regards.
Hello Alex Yakhnin [MVP],

Thank you. Please tell me the type of the buf below and how can I
access it from my c# code.

struct PimData
{
public int id;
public string buf; // <-- this is declared in C++ as char
1024.
should it be TCHAR ?
}
I am new to this interop and has no clue. I have looked at various
previous posts and most of them talk about passing a string but not a
custom structure from c++.

Regards.
The problem is in your Data structure. The marshaler is choking on
the public string buf member.

--
Alex Yakhnin, .NET CF MVP
www.intelliprog.com | www.opennetcf.org
New Bee said:
I have a C++ app that is sending the following data to a C# app
through WM_COPYDATA message. The below is the custom structre that I
am sending.

C++ code:
========
struct sData
{
private:
int id;
char szData[1024];
public:
sData()
{
memset(this, NULL, sizeof(sData));
}
public:
void SetData(int iApp, char* pszData)
{
id = iApp;
strcpy(szData, pszData);
}
};
sData data;
data.SetData(1, "Hello! from Native code.");

COPYDATASTRUCT ds;
ds.dwData = (WPARAM)0;
ds.cbData = sizeof(sData);
ds.lpData = &data;
r = SendMessage(hCWnd, WM_COPYDATA, (WPARAM)0, (LPARAM)&ds);

C# code:
=======
struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}
struct Data
{
public int id;
public string buf;
}
In a class that implements MessageWindow.
protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT ds =
(COPYDATASTRUCT)Marshal.PtrToStructure(msg.LParam,
typeof(COPYDATASTRUCT));
Data data = (Data)Marshal.PtrToStructure(ds.lpData, typeof(Data));
// <<--- Give me unsupported error
}
......
......
......
 
N

New Bee

I got the size wrong in my previous post. Correct size of the TCHAR is 500.

TCHAR szPimData[500];
Thanks everybody.

I got it this time. Changed my structure to this.

[StructLayout(LayoutKind.Sequential)]
struct Data
{
public int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string buf;
}
Also changed my C++ code from

char szData[1024];

to TCHAR szPimData[1024];

Everything works fine now.

Regards.
Hello Alex Yakhnin [MVP],

Thank you. Please tell me the type of the buf below and how can I
access it from my c# code.

struct PimData
{
public int id;
public string buf; // <-- this is declared in C++ as char
1024.
should it be TCHAR ?
}
I am new to this interop and has no clue. I have looked at various
previous posts and most of them talk about passing a string but not a
custom structure from c++.
Regards.
The problem is in your Data structure. The marshaler is choking on
the public string buf member.

--
Alex Yakhnin, .NET CF MVP
www.intelliprog.com | www.opennetcf.org
:
I have a C++ app that is sending the following data to a C# app
through WM_COPYDATA message. The below is the custom structre that
I am sending.

C++ code:
========
struct sData
{
private:
int id;
char szData[1024];
public:
sData()
{
memset(this, NULL, sizeof(sData));
}
public:
void SetData(int iApp, char* pszData)
{
id = iApp;
strcpy(szData, pszData);
}
};
sData data;
data.SetData(1, "Hello! from Native code.");
COPYDATASTRUCT ds;
ds.dwData = (WPARAM)0;
ds.cbData = sizeof(sData);
ds.lpData = &data;
r = SendMessage(hCWnd, WM_COPYDATA, (WPARAM)0, (LPARAM)&ds);
C# code:
=======
struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}
struct Data
{
public int id;
public string buf;
}
In a class that implements MessageWindow.
protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT ds =
(COPYDATASTRUCT)Marshal.PtrToStructure(msg.LParam,
typeof(COPYDATASTRUCT));
Data data = (Data)Marshal.PtrToStructure(ds.lpData, typeof(Data));
// <<--- Give me unsupported error
}
......
......
......
 
D

davidlin1980

I've been struggling with WM_COPYDATA myself where I tried to send
messages from one C# application to another C# application

For those who are interested, here are some code fragments that work
for me:

// structures and constants
==========================================

const uint WM_COPYDATA = 0x004A;

[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage
(IntPtr handle, uint Msg, IntPtr wParam, ref COPYDATASTRUCT
lParam);

struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct UserData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=200)]
public string tag;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
public string msg;
}


// sender code
//==========================================
{
COPYDATASTRUCT data;

data.dwData = 3; // whatever value (have to match receiver end)
data.cbData = 400; // size of UserData struct (I have two 200 bytes
long ANSI array)

UserData userData;
userData.tag = "Tag";
userData.msg = "Message";

data.lpData = Marshal.AllocCoTaskMem(data.cbData);
Marshal.StructureToPtr( userData, data.lpData, true);

SendMessage( targetHandle, WM_COPYDATA, this.Handle, ref data );

Marshal.FreeCoTaskMem(data.lpData);
}

// receiver end end
//==========================================

protected override void WndPrc( ref Message m)
{
if( m.Msg == WM_COPYDATA )
{
COPYDATASTRUCT data =
(COPYDATASTRUCT)Marshal.PtrToStructure
(m.LParam, typeof(COPYDATASTRUCT));
if( data.dwData == 3 )
{
UserData userData =
(UserData)Marshal.PtrToStructure(data.lpData,
typeof(UserData));
// Access userData as wish
// ...
}
}
...
}
 

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