我是否需要一个包装器 class 用于 p/invoke'ing 来自 user32.dll 的一些函数
Do I need a wrapper class for p/invoke'ing a few functions from user32.dll
所以我正在开发一个 c# Windows 表单应用程序,我的部分代码使用了 user32.dll 中的一些方法。下面列出了它们。
- public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
- public static extern bool ReleaseCapture();
- public static extern IntPtr GetForegroundWindow();
- public static extern int GetWindowText(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
- public static extern uint GetWindowThreadProcessId
- public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii)
起初我将它们放在文件中,所有主要表单代码作为 public partial class MainForm
的一部分,这一切都有效。然后,当我在 Visual Studio Community 2015 中进行 运行 代码分析时,它抱怨说“因为它们是 P/Invoke 方法,所以它们应该在名为 NativeMethods、SafeNativeMethods 或 UnsafeNativeMethods 的 class 中定义。
所以作为一个优秀的编码员,我总是服从他的突发奇想 IDE 我立即制作了一个新的 class 文件并 运行 进入第一期。
Would the class containing these functions be unsafe (is it also unmanaged)? Which name
should I use and should the class be declared as internal static
with the [DebuggerNonUserCode]
attribute?
当我阅读更多内容以尝试弄清楚这一点时,我不断遇到为代码制作包装器 class 的参考资料,所以我开始研究它。这产生了大量关于 c++ 或 c 的安全性和包装器、原型和大量其他似乎没有帮助的信息,让我完全迷失了方向。
So I guess what I want to know is two things. 1st, would I need to (or
would it be best practice to do so) make a wrapper class to use these
methods, and if so, how would I go about doing it?
2nd, If I make the class Unsafe/SafeNativeMethods should I call it
safe or unsafe? Should all the methods be left public? Or do should
have the methods declared private and write some getters/setters like:
public IntPtr getGetForegroundWindow()
{
return GetForegroundWindow()
}
或
public setSendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr, lParam)
{
SendMessage(hWnd, Msg, wParam, lParam);
}
或者我是否需要使用委托或其他东西来代替 setter 和 getter?
抱歉这个问题有点脑残。每次我认为我找到了答案,但我最终都会提出更多问题,safe/unsafe/security 的所有谈话都让我担心。我不介意 google 搜索和阅读主题,但阅读列表只是为了弄清楚要阅读的内容越来越多,所以我想我会停下来问这里看看我是否问了正确的问题。提前致谢。
我会创建一个静态 class。
namespace NativeMethods
{
public static class User32
{
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref RECT lParam);
}
}
仅在包装器执行某些操作时创建包装器,例如保持参数状态 conversion/checking。
想要包装 pInvokes 的情况
包装 PInvoke 方法的示例可能是当本机方法分配内存和 returns 句柄时。在这种情况下,您需要创建一个包装器来跟踪句柄。它应该实现 IDisposable
以释放非托管资源。
对于(伪)示例:(你应该检查处置模式)
public class MyWrapper : IDisposable
{
[DllImport("MyLibrary.dll")]
private static extern IntPtr DoAllocSomeMemory(int size);
[DllImport("MyLibrary.dll")]
private static extern void ReleaseMe(IntPtr handle);
private IntPtr _handle;
public MyWrapper()
{
_handle = DoAllocSomeMemory(8000);
}
public void Dispose()
{
ReleaseMe(_handle);
}
}
所以我正在开发一个 c# Windows 表单应用程序,我的部分代码使用了 user32.dll 中的一些方法。下面列出了它们。
- public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
- public static extern bool ReleaseCapture();
- public static extern IntPtr GetForegroundWindow();
- public static extern int GetWindowText(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
- public static extern uint GetWindowThreadProcessId
- public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii)
起初我将它们放在文件中,所有主要表单代码作为 public partial class MainForm
的一部分,这一切都有效。然后,当我在 Visual Studio Community 2015 中进行 运行 代码分析时,它抱怨说“因为它们是 P/Invoke 方法,所以它们应该在名为 NativeMethods、SafeNativeMethods 或 UnsafeNativeMethods 的 class 中定义。
所以作为一个优秀的编码员,我总是服从他的突发奇想 IDE 我立即制作了一个新的 class 文件并 运行 进入第一期。
Would the class containing these functions be unsafe (is it also unmanaged)? Which name should I use and should the class be declared as
internal static
with the[DebuggerNonUserCode]
attribute?
当我阅读更多内容以尝试弄清楚这一点时,我不断遇到为代码制作包装器 class 的参考资料,所以我开始研究它。这产生了大量关于 c++ 或 c 的安全性和包装器、原型和大量其他似乎没有帮助的信息,让我完全迷失了方向。
So I guess what I want to know is two things. 1st, would I need to (or would it be best practice to do so) make a wrapper class to use these methods, and if so, how would I go about doing it?
2nd, If I make the class Unsafe/SafeNativeMethods should I call it safe or unsafe? Should all the methods be left public? Or do should have the methods declared private and write some getters/setters like:
public IntPtr getGetForegroundWindow()
{
return GetForegroundWindow()
}
或
public setSendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr, lParam)
{
SendMessage(hWnd, Msg, wParam, lParam);
}
或者我是否需要使用委托或其他东西来代替 setter 和 getter?
抱歉这个问题有点脑残。每次我认为我找到了答案,但我最终都会提出更多问题,safe/unsafe/security 的所有谈话都让我担心。我不介意 google 搜索和阅读主题,但阅读列表只是为了弄清楚要阅读的内容越来越多,所以我想我会停下来问这里看看我是否问了正确的问题。提前致谢。
我会创建一个静态 class。
namespace NativeMethods
{
public static class User32
{
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref RECT lParam);
}
}
仅在包装器执行某些操作时创建包装器,例如保持参数状态 conversion/checking。
想要包装 pInvokes 的情况
包装 PInvoke 方法的示例可能是当本机方法分配内存和 returns 句柄时。在这种情况下,您需要创建一个包装器来跟踪句柄。它应该实现 IDisposable
以释放非托管资源。
对于(伪)示例:(你应该检查处置模式)
public class MyWrapper : IDisposable
{
[DllImport("MyLibrary.dll")]
private static extern IntPtr DoAllocSomeMemory(int size);
[DllImport("MyLibrary.dll")]
private static extern void ReleaseMe(IntPtr handle);
private IntPtr _handle;
public MyWrapper()
{
_handle = DoAllocSomeMemory(8000);
}
public void Dispose()
{
ReleaseMe(_handle);
}
}