4

我需要将字符串从 C# 发送到 C++ WindowProc。关于 SO 有许多与此相关的相关问题,但没有一个答案对我有用。情况如下:

PInvoke:
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, string lParam);

C#:
string lparam = "abc";
NativeMethods.User32.SendMessage(handle, ConnectMsg, IntPtr.Zero, lparam);

C++:
API LRESULT CALLBACK HookProc (int code, WPARAM wParam, LPARAM lParam)
{       
    if (code >= 0)
    {
        CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
                ...
        (LPWSTR)cwp->lParam   <-- BadPtr
                ...
    }

    return ::CallNextHookEx(0, code, wParam, lParam);
}

我尝试了许多不同的方法,将字符串编组为 LPStr、LPWStr,还尝试从非托管内存创建一个 IntPtr,并使用 Marshal.WriteByte 写入它。

指针是 C++ 端的正确内存位置,但数据不存在。我错过了什么?

4

2 回答 2

2

对于 C++LPWSTRLPSTR参数,您需要StringBuilder在 DllImport 中使用 C#。

对于 C++LPCWSTRLPCSTR参数,您需要string在 DllImport 中使用 C#。

于 2010-04-16T14:29:34.690 回答
1

确保您的 SendMessage 调用以预期的同步方式发生,并且您的 NativeMethods 类映射正确的 Win32 调用(Send 与 PostMessage。)如果这不正确,则可能在 C++ 上处理您的消息时最后,您已经离开了 C# 方法的范围,并且在堆栈上创建的任何局部变量都消失了,从而导致您的指针错误。

跨线程调用的堆栈和堆注意事项:线程有自己的堆栈但共享堆。一个线程中的堆栈分配变量在另一个线程中不可见。字符串类型是 .NET 中的一个奇怪的鸭子。它是对象派生的引用类型,但在代码中看起来和感觉上都像值类型。所以也许传递一个指向堆分配数据的指针应该可以工作。这就是作为堆分配引用类型的 StringBuilder 的用武之地。

于 2010-04-16T14:36:03.070 回答