好吧,我正在尝试调用AET60.dll中的函数,其中包含用于AET60 BioCARDKey(指纹和智能卡读卡器)的API和c#;实际上,除了操纵指纹模板的那些功能外,我几乎成功地调用了所有功能:捕获,匹配,注册。 我确定它是参数类型的问题,但问题是我无法解决模板参数的类型,例如dll函数捕获,需要一个字节指针(byte *)来保存模板,我'尝试使用ref和不安全的代码(用于使用指针),如果直接从控制台应用程序调用(并在同一个类中导入dll),它可以正常工作,但指向的值只是一个字节(0-255),并且在那里我迷路了(256个代码不足以识别超过6个biliion人,所以我认为那个字节*实际上类似于c字符串:char *,但我不知道如何在c#中使用它)。 另一个问题是,如果此dll函数封装在方法中,则在尝试使用模板数据时会抛出AccesViolationException。 这是一些代码:
public class NativeMethods
{
private static const Int32 DEFAULT_TIMEOUT = 10000;
[DllImport("AET60.dll")]
private static extern UInt32 AET60_Open();
[DllImport("AET60.dll")]
private static extern UInt32 AET60_Close();
[DllImport("AET60.dll")]
private static extern Int32 AET60_GetNumDevices();
[DllImport("AET60.dll")]
private static extern UInt32 AET60_GetDeviceName(Int32 index, StringBuilder name, ref int nameLength);
[DllImport("AET60.dll")]
private static extern UInt32 AET60_GetMessage(int number, StringBuilder message);
[DllImport("AET60.dll")]
private static extern UInt32 AET60_GetLastStatus();
[DllImport("AET60.dll")]
private static extern UInt32 AET60_GetStatus(UInt32 status, StringBuilder message);
[DllImport("AET60.dll")]
private static extern UInt32 AET60_LockReader(Int32 index);
[DllImport("AET60.dll")]
private static extern UInt32 AET60_UnlockReader();
[DllImport("AET60.dll")]
private static extern UInt32 AET60_Capture(ref byte template, ref Int32 templateLength, UInt32 timeOut);
public static void capture(Template template)
{
Byte templateData = template.Data;
Int32 templateLength = template.Length;
Int32 numberOfDevices;
UInt32 errorCode = NativeMethods.AET60_Open(); //for now Im doing nothing with errorCode
numberOfDevices = NativeMethods.AET60_GetNumDevices();
errorCode = NativeMethods.AET60_LockReader(numberOfDevices - 1);
errorCode = NativeMethods.AET60_Capture(ref templateData, ref templateLength, DEFAULT_TIMEOUT);
errorCode = NativeMethods.AET60_UnlockReader();
template.Data = templateData; //here is thrown the exception
template.Length = templateLength; //here is thrown the exception
errorCode = NativeMethods.AET60_Close();
}
}
在此代码中,抛出AccesViolationExeption。除了AET60_Capture之外,列出的每个其他dll函数都可以正常工作。
Template类是一个包含byte和Int32字段的简单类。
感谢您的帮助!
答案 0 :(得分:0)
我找到了解决方案,可能对某人有用。
整个问题就像我原先想到的那样,模板的类型,不在参数中,而是在应用程序中。它必须是byte [](字节数组),并且传递的参数(in)必须是第一个数组位置,我不记得基本原理,数组实际上是指向内存中序列结构的第一个元素的指针,第二个参数(长度)保存数组大小。 这是新代码:
public static void capture(ref Template template)
{
if (template == null)
{
template = new Template();
}
Int32 templateLength = template.Length;
Byte[] templateData = new Byte[templateLength];
Int32 numberOfDevices;
UInt32 errorCode = FingerPrintReader.AET60_Open();
numberOfDevices = FingerPrintReader.AET60_GetNumDevices();
errorCode = FingerPrintReader.AET60_LockReader(numberOfDevices - 1);
errorCode = FingerPrintReader.AET60_Capture(ref templateData[0], ref templateLength, DEFAULT_TIMEOUT);
errorCode = FingerPrintReader.AET60_UnlockReader();
errorCode = FingerPrintReader.AET60_Close();
Byte[] auxTemplateData = new Byte[templateLength];
for (int i = 0; i < templateLength; i++)
{
auxTemplateData[i] = templateData[i];
}
template.Data = auxTemplateData;
template.Length = templateLength;
}
最后一部分是重新调整数组,因为默认长度是1024,但是templateData数组总是更小。