gpt4 book ai didi

c# - 没有 SafeHandle 的 DllImport 导致 MissingMethodException

转载 作者:太空宇宙 更新时间:2023-11-03 22:56:42 24 4
gpt4 key购买 nike

我在 C# 中为 QuickUsb 编写了一个包装类来访问非托管库。有关完整的实现,请参阅此 gist .

本题的主要兴趣点有以下几个部分:

public class QuickUsbPort
{
private class SafeQuickUsbHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("QuickUsb.dll", CharSet = CharSet.Ansi)] static extern
int QuickUsbClose(IntPtr handle);

public SafeQuickUsbHandle(IntPtr handle) : base(true)
{
SetHandle(handle);
}

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return QuickUsbClose(handle) != 0;
}
}

private static class NativeLib
{
[DllImport("QuickUsb.dll", CharSet = CharSet.Ansi)] static extern
int QuickUsbOpen(out SafeQuickUsbHandle handle, string deviceName);

public static SafeQuickUsbHandle Open(string deviceName)
{
if (QuickUsbOpen(out SafeQuickUsbHandle handle, deviceName) == 0)
{
throw new QuickUsbException("Open", new List<Tuple<string, string>>
{
new Tuple<string, string>("deviceName", deviceName),
});
}
return handle;
}
}
}

handle 编码为 SafeQuickUsbHandle 似乎存在问题,因为在调用 Open() 时此代码会抛出 MissingMethodException。然而,以下修改不会引发此类异常:

        [DllImport("QuickUsb.dll", CharSet = CharSet.Ansi)] static extern
int QuickUsbOpen(out IntPtr handle, string deviceName);

public static SafeQuickUsbHandle Open(string deviceName)
{
if (QuickUsbOpen(out IntPtr handle, deviceName) == 0)
{
throw new QuickUsbException("Open", new List<Tuple<string, string>>
{
new Tuple<string, string>("deviceName", deviceName),
});
}
return new SafeQuickUsbHandle(handle);
}

所以我想知道我是否遗漏了我的 SafeQuickUsbHandle 实现的某些方面,以允许 c# 正确编码和处理句柄。

注意在dll中,handle是指向句柄的指针:

/// <param name="handle">
/// A PQHANDLE that points to a QHANDLE in which to place the new device ID.
/// If successful, hDevice will contain the new QHANDLE</param>

最佳答案

您必须为派生自 SafeHandle 的类提供公共(public)无参数构造函数,尤其是当您使用 p/invoke 时,定义如下:SafeHandle

Your subclass of SafeHandle is only required to provide three methods

.ctor() – A default constructor that initializes the SafeHandle. This method is used by P/Invoke when it returns a SafeHandle to your process

bool IsInvalid { get; } – a property to determine if the current value of the handle is valid or not

bool ReleaseHandle() – clean up the contained resource

p/invoke 无论如何都会神奇地设置值。它也在 official documentation 中:

When you inherit from SafeHandle, you must override the following members: IsInvalid and ReleaseHandle. You should also provide a default constructor that calls the base constructor with a value that represent an invalid handle value, and a Boolean value indicating whether the native handle is owned by the SafeHandle and consequently should be freed when that SafeHandle has been disposed.

由于 SafeHandleZeroOrMinusOneIsInvalid 没有定义公共(public)无参数构造函数,您必须这样做。

关于c# - 没有 SafeHandle 的 DllImport 导致 MissingMethodException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45064120/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com