P / Invoke更改传递的参数的值

时间:2016-07-16 15:38:19

标签: c# c++ pinvoke native unmanaged

所以我在DLL中有这个c ++函数

which createpd -all

以下是我的c#项目:

__declspec(dllexport) MOUSERAWDATA __stdcall GetMouseRawData(LPARAM lParam)
{
    UINT bufferSize = 0;
    BYTE *buffer = new BYTE[bufferSize];
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &bufferSize, sizeof(RAWINPUTHEADER));
    RAWINPUT *raw = (RAWINPUT*)buffer;
    MOUSERAWDATA data;
    if (raw->header.dwType == RIM_TYPEMOUSE)
    {
        data.longX = raw->data.mouse.lLastX;
        data.longY = raw->data.mouse.lLastY;
    }
    return data;
}

当我运行此代码时,以下值将传递给GetMouseRawData

The value being passed

但由于某种原因,C ++方面的lParam值始终不同。

enter image description here

我的情况是0x004fe95c = 5237084

任何人都知道为什么会这样?

1 个答案:

答案 0 :(得分:1)

您正在分配0长度的缓冲区。然后"问"缓冲区的大小应该是多少。然后通过告诉他们您的缓冲区大小正确来说谎GetRawInputData。将缓冲区分配移动到第一次调用之后,您已经学习了所需的缓冲区大小。

UINT bufferSize = 0;
BYTE *buffer = new BYTE[bufferSize];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &bufferSize, sizeof(RAWINPUTHEADER));
RAWINPUT *raw = (RAWINPUT*)buffer;

您需要delete[]缓冲区以防止泄漏。 您需要初始化data(MOUSERAWDATA)以防止它有条件地包含垃圾。调用者将如何知道raw->header.dwType == RIM_TYPEMOUSE是真还是假?

您是否考虑过根据Microsoft guidance直接调整GetRawInputData():

public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, out RAWINPUT pData, ref int pcbSize, int cbSizeHeader);

protected override void WndProc(ref Message m)
{
    if (m.Msg == (int)WindowMessages.RawInput)  // WindowMessages.RawInput = 0x00FF (WM_INPUT)
    {
        RAWINPUT input = new RAWINPUT();
        int outSize = 0;
        int size = Marshal.SizeOf(typeof(RAWINPUT));

        outSize = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, out input, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER)));
        if (outSize != -1)
        {
            if (input.Header.Type == RawInputType.Mouse)
            {
                //input.Mouse.LastX;
                //input.Mouse.LastY;
            }
        }
    }
    base.WndProc(ref m);
}