【问题标题】:C# string to long pointerC#字符串到长指针
【发布时间】:2010-06-22 15:09:28
【问题描述】:

我正在处理需要向 C++ 应用程序发送消息的 C# 应用程序。

我导入了

[DllImport("user32.dll")]
        public static extern IntPtr SendMessage(
              int hWnd,      // handle to destination window
              uint Msg,       // message
              IntPtr wParam,  // first message parameter
              IntPtr lParam   // second message parameter
              );

但现在,我的问题是 我需要将字符串传递给 wParam 和 lParam。我尝试了不安全的代码,但似乎字符串不像其他变量那样工作。我怎样才能做到这一点?谢谢。

【问题讨论】:

  • 我相信MarshalAs 属性是有序的。

标签: c# string pointers long-integer


【解决方案1】:

声明错误,wParam和lParam参数都是IntPtr,不长。

因为您尝试发送字符串,所以有一个复杂的问题。目标窗口是否启用 Unicode 很重要。 SendMessage 有两个版本,SendMessageA() 和 SendMessageW()。如果程序过时并且使用 8 位字符串而不是 UTF-16 编码的字符串,则需要使用前者。

您可以使用 Spy++ 找出答案。使用查找工具选择应用程序的窗口。在“常规”属性选项卡中,您将看到“Window proc”。如果窗口启用了 Unicode,它将显示 (Unicode)。如果看不到,则必须将字符串转换为 8 位字符。

要生成需要传递的字符串指针,可以使用 Marshal.StringToHGlobalAnsi 或 StringToHGlobalUni(分别为 8 位和 Unicode)。但是,您可以使用一个技巧让 P/Invoke marshaller 为您翻译字符串。省去通话后必须释放字符串的麻烦。对于 Ansi 版本,您可以像这样声明 API 函数:

    [DllImport("user32.dll", CharSet = CharSet.Ansi, EntryPoint = "SendMessageA", ExactSpelling = true)]
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);

Unicode 版本是这样的:

    [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW", ExactSpelling = true)]
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);

最后一点:如果窗口属于另一个应用程序,这将无法按原样工作,您将使其崩溃。您传递的指针值仅在您自己的进程中有效,在 C++ 进程中无效。要解决这个问题,您必须在目标进程中分配内存以使指针有效。这需要 OpenProcess 获取进程的句柄,VirtualAllocEx() 在目标进程中分配内存,大到足以存储字符串,WriteProcessMemory 来写入字符串。现在您可以调用 SendMessage(),使用用 IntPtr 声明的版本作为 wParam 和 lParam 参数,传递您从 VirtualAllocEx 获得的值。接下来使用 VirtualFreeEx() 释放内存并使用 CloseHandle 进行清理。或者,如果您经常这样做,请保留下一次的记忆。

相当多的 P/Invoke 在那里出错。不说安全问题,WriteProcessMemory 需要管理员权限,需要 UAC 提升。

【讨论】:

  • 关于你的“最后说明”,你有一些代码示例吗?因为我现在很迷茫。是的,目标应用程序是另一个应用程序(就像我说的,它从 C# 应用程序到 C++ 应用程序)我有目标应用程序进程,我的问题是将字符串传递给它。
  • 我给你的API函数列表很好googles。这个查询的第一个命中看起来不错:google.com/…
【解决方案2】:

传递字符串的地址会涉及不安全的代码, 因为 Win32 API 调用需要地址(在 C/C++ 本机环境中)。您发送的哪些 Windows 消息需要 wParam 或 lParam 中的字符串?

【讨论】:

  • 自定义消息。而且我不能通过字符串的地址。它只是不想构建它。
【解决方案3】:

我们最终使用“WmCpyDta_d.dll”来处理所有这些问题。

【讨论】:

  • 虽然这解决了您的问题,但这是一种解决方法,不应该成为您问题的公认解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2021-06-28
  • 2023-03-15
相关资源
最近更新 更多