2013-05-16 37 views
-1

我的C#代码将消息发送到WM_COPYDATA如何从C复制COPYDATASTRUCT消息?

public static bool SendArgs(IntPtr targetHWnd, string args) 
     { 
      Win32.CopyDataStruct cds = new Win32.CopyDataStruct(); 
      try 
      { 
       cds.cbData = (args.Length + 1) * 2; 
       cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); 
       Marshal.Copy(args.ToCharArray(), 0, cds.lpData, args.Length); 
       cds.dwData = (IntPtr)1; 
       Win32.SendMessage(targetHWnd, Win32.WM_COPYDATA, IntPtr.Zero, ref cds); 
      } 
      finally 
      { 
       cds.Dispose(); 
      } 

      return true; 
     } 

我的C代码,以接收消息

static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, 
       WPARAM wParam, LPARAM lParam) 
{ 
switch (message) { 
case WM_COPYDATA: 
      { 

COPYDATASTRUCT* copy_data = (COPYDATASTRUCT*)(lParam); 

      const char* str = (const char*)(copy_data->lpData); 
      /* Also fixed the parameter list for "%.*s" */ 
    printf("Message (%u): %.*s\n", copy_data->dwData, (int)copy_data->cbData, str); 
} 
} 
} 

使用上面的代码中检索到消息的第一个字符,而不是所有的内容

+0

出了什么问题?它是否编译?它会崩溃吗?它会给出错误的输出吗? – dutt

+1

只需将'C'-style cast替换为'reinterpret_cast'即可。无论如何,它们本质上意味着同样的事情 – Chad

+0

@Chad你暗示C++强制转换不起作用吗? –

回答

3

你的意思是这样的?

if (message == WM_COPYDATA) 
{ 
    COPYDATASTRUCT* copy_data = (COPYDATASTRUCT)(lparam); 

    const char* str = (const char*)(copy_data->lpData); 

    /* Also fixed the parameter list for "%.*s" */ 
    printf("Message (%u): %.*s\n", copy_data->dwData, (int)copy_data->cbData, str); 
} 

当然打印copy_data->lpData作为字符串只会意义,如果它真的是字符串数据。

+1

还要考虑'copy_data-> lpData'可以是NULL(如果这是调用者最初传入的内容,这是完全有效的)。 –

+0

确实。否则,你的手中就有一个微不足道的缓冲区溢出漏洞。 –

+0

@DavidHeffernan它工作正常,但它检索字符串的第一个字符它不检索整个字符串我如何实现这一点。 – Siva

0

我检索消息的第一个字符,而不是所有的内容。

这表示该字符串被编码为UTF-16,并且可以从C#代码中看到,它生成的消息表明您发送的数据是UTF-16编码的。

另一方面,您的C代码将其视为8位ANSI编码。这就是为什么C代码无法正确读取它的原因。如果您的C代码将其视为UTF-16,那么您将获得所有内容。

您不能假定该字符串以空字符结尾,并应使用cbData来避免缓冲区溢出。

所以,你可以改变你的C代码是像这样:

COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam; 
int len = (cds->cbData/2)-1; 
printf("Message (%u): %.*S\n", cds->dwData, len, cds->lpData); 

注意%.*S将把输入作为UTF-16编码字符串,然后打印速度比len的个字符。

我还假设您使用的是Microsoft的工具,因为S格式类型是非标准的Microsoft特殊格式。如果你想要可移植,那么有办法做到这一点,但我不确定你是否准备好解决这个问题。

+0

其实我从c#应用程序发送消息到c应用程序,我不知道如何将指针转换为wchar_t *。你能提供代码示例 – Siva

+0

我不提供代码,直到你解决你的问题。你说这个语言是C,但显然它是C++。你不会在它如何失败的问题上提供任何细节。你也不会显示C#代码。所以,一旦你这样做,我会走得更远。您已经设法将其转换为char *,看看您是否可以猜测如何转换为wchar_t *。我确信我的回答是准确的,我很抱歉,您没有发现它有帮助。 –

+0

现在我编辑了我的问题。我提供了整个C#以及C代码。为我提供解决方案。 – Siva