我想使用 winmm dll 捕获来自操纵杆的输入。我对导入和使用 DLL 知之甚少。
我试图做到这一点,但我不知道该怎么做..
[DllImport("winmm.dll")]
public static extern string joyGetPosEx(uint dev, JoyinfoEx ) //Something Similar
如何从 DLL 中获取 joyinfoEx 结构并将其放入 JoygetPosEx ..?:S
正如您的问题所暗示的,您必须joyGetPosEx
从wimmm.dll
. 这通常称为P/Invoking,因为您从本机 Win32 API(或“平台”DLL)调用函数。您已经知道需要使用该功能,所以让我们更仔细地看一下。
该函数的文档表明它需要两个参数:
第一个 ( uJoyID
) 是一个简单int
(或整数)值,用于标识要查询的操纵杆。
第二个 ( pji
) 比第一个复杂一点,我认为这是您正在努力解决的部分。它不是标准值类型,而是一个名为 的结构JOYINFOEX
,您必须在代码中定义该结构。该joyGetPosEx
函数的作用是用有关操纵杆位置的信息填充该特殊结构,允许它一次返回一堆不同的值。这就是为什么您必须将其作为引用 ( ref
) 传递的原因,因为该函数实际上会用一组值填充您传递给它的结构的实例。然后,您的代码可以从包含结构实例的变量中读取这些值。
该结构的文档可用在这里,它会告诉您
每个成员的名称和数据类型。您可以将 aDWORD
视为int
,因此它的声明如下所示:
[StructLayout(LayoutKind.Sequential)]
public struct JOYINFOEX
{
public int dwSize;
public int dwFlags;
public int dwXpos;
public int dwYpos;
public int dwZpos;
public int dwRpos;
public int dwUpos;
public int dwVpos;
public int dwButtons;
public int dwButtonNumber;
public int dwPOV;
public int dwReserved1;
public int dwReserved2;
}
最后,该joyGetPosEx
函数返回一个 type 的值int
。这个值告诉你函数是否成功,如果没有成功,究竟出了什么问题。这是一个错误代码。上面链接的文档为您提供了可以返回的所有可能值的表格。如果要检查这些值,则需要在代码中将它们定义为常量:
public const int JOYERR_BASE = 160
public const int JOYERR_PARMS = (JOYERR_BASE + 5);
public const int JOYERR_UNPLUGGED = (JOYERR_BASE + 7);
public const int MMSYSERR_BASE = 0;
public const int MMSYSERR_BADDEVICEID = (MMSYSERR_BASE + 2);
public const int MMSYSERR_INVALPARAM = (MMSYSERR_BASE + 11);
因此,鉴于上述情况,最终的函数定义如下所示:
[DllImport("winmm.dll")]
public static extern int joyGetPosEx(int uJoyID, ref JOYINFOEX pji);
将来,请记住pinvoke.net作为如何在代码中定义和声明这些 Win32 API 函数的参考。它没有碰巧有这个joyGetPosEx
功能(或者至少不是我发现的那个),但它通常几乎有你需要的一切。然后如果失败了,你可以按照我上面解释的那样做:查看函数的原始文档并尝试找出相应地定义它以在 .NET 中工作。
该函数通过第二个参数返回数据。返回值是一个整数,表示任何可能的错误。正确的声明是:
[DllImport("winmm.dll")]
private static extern int joyGetPosEx(int joystickNumber, ref JOYINFOEX info);
您必须像这样声明结构:
[StructLayout(LayoutKind.Sequential)]
private struct JOYINFOEX {
public int dwSize;
public int dwFlags;
public int dwXpos;
public int dwYpos;
public int dwZpos;
public int dwRpos;
public int dwUpos;
public int dwVpos;
public int dwButtons;
public int dwButtonNumber;
public int dwPOV;
public int dwReserved1;
public int dwReserved2;
}
示例调用:
JOYINFOEX info = new JOYINFOEX();
info.dwSize = Marshal.SizeOf(info);
int err = joyGetPosEx(1, ref info);
if (err != 0) reportError(err);
else {
int xpos = info.dwXpos;
// Do something with xpos
//...
}