我编写了一个包装类来访问c#for QuickUsb中的非托管lib。对于完整的实现,请参阅此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>
答案 0 :(得分:3)
您必须为从SafeHandle派生的类提供公共无参数构造函数,尤其是当您使用p / invoke时,如此处所定义:SafeHandle
您的SafeHandle子类只需要提供三种方法
.ctor() - 初始化SafeHandle的默认构造函数。这个 P / Invoke在将SafeHandle返回给你的时使用它 过程
bool IsInvalid {get; } - 确定是否的属性 句柄的当前值是否有效
bool ReleaseHandle() - 清理包含的资源
p / invoke无论如何都会神奇地设置值。它也出现在official documentation:
中从SafeHandle继承时,必须覆盖以下内容 成员:IsInvalid和ReleaseHandle。你还应该提供一个 默认构造函数,使用值调用基础构造函数 表示无效的句柄值,以及指示的布尔值 本机句柄是否由SafeHandle拥有,因此 在处理好SafeHandle时应该释放。
由于import numpy as np
qts.index = np.round(qts.index, decimals=1)
没有定义公共无参数构造函数,所以必须这样做。