2016-07-16 10 views
0

Так что я это Си ++ в DLLP/Invoke изменяет значения переданных аргументов

__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; 
} 

И следующее в моей C# проекта:

[DllImport("RawInput.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern MouseRawData GetMouseRawData(IntPtr lParam); 
. 
. 
. 
protected override void WndProc(ref Message m) 
{ 
    switch(m.Msg) 
    { 
     case WM_CREATE: 
      if (AttachMouseListener(this.Handle)) 
       Console.WriteLine("It works!"); 
      break; 
     case WM_INPUT: 
      MouseRawData data = GetMouseRawData(m.LParam); 
      break; 
     default: 
      base.WndProc(ref m); 
      break; 
    } 
} 

Когда я запускаю этот код, следующее значение передается GetMouseRawData

The value being passed

Но для некоторых REAS на значение lParam на стороне C++ всегда разные.

enter image description here

Я этот случай 0x004fe95c = 5237084

Любой знает, почему это происходит?

+1

Ваше объявление PInvoke не совпадает с функцией C. Вероятно, из-за декларации MouseRawData у нас есть преимущество не видеть, функции, возвращающие структуру, всегда сложны. Вместо этого используйте bool GetMouseRawData (данные LPARAM lParam, MOUSERAWDATA *). –

ответ

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; 

Для предотвращения утечки необходимо заполнить ваш буфер, чтобы предотвратить утечку. Вам необходимо инициализировать data (MOUSERAWDATA), чтобы предотвратить условное содержание мусора. Как вы узнаете, что raw->header.dwType == RIM_TYPEMOUSE был правдой или ложью?

Рассматривали ли вы просто pinvoking GetRawInputData() непосредственно в Microsoft guidance:

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); 
} 
+0

Спасибо за ввод. Но ваш ответ не говорит мне, почему передаваемая стоимость меняется. – Abhinav

+0

Можете ли вы подтвердить, что вы строите свой .net и ваш C++ с той же биттой? Оба 64-битных или оба 32-битных. IntPtr будет другого размера. –