将Suprema Biostar C ++代码转换为C#

时间:2015-02-03 07:39:47

标签: c# c++ pointers biometrics

我从Suprema获得了Biostation T2,他们提供了一个用C#编写的包装Dll,他们还提供了使用的示例:VB6,VB.net,C ++和C#。大部分文档都是用C ++编写的,我很难尝试将该逻辑转换为C#。我无法在pastie中使用以下函数注册用户。主要原因是我不确定C#和C ++中的逻辑是否匹配。

请参阅C++ code for enrolling user and my C# attempt pastie

我在尝试读取或写入受保护的内存时遇到错误enter image description here

这里是他们提供的sdk样本链接sdk samples in vc,c#,C++

1 个答案:

答案 0 :(得分:1)

我们无法使用您向我们展示的内容编译和测试您的代码。话虽这么说,并排比较c ++和c#,我看到以下不一致:

  1. c ++具有以下代码:

    unsigned char* templateBuf = (unsigned char*)malloc( userHeader.numOfFinger * 2 * BS_TEMPLATE_SIZE );
    int bufPos = 0;
    for( int i = 0; i < userHeader.numOfFinger * 2; i++ )
    {
        result = BS_ScanTemplate( handle, templateBuf + bufPos );
        bufPos += BS_TEMPLATE_SIZE;
    }
    

    此代码多次调用BS_ScanTemplate并将结果按顺序存储在字节数组中。您的代码执行以下操作:

        byte[] templateBuf = new byte[userHdr.numOfFinger * 2 * BS_TEMPLATE_SIZE];
        int bufPos = 0;
        for (int i = 0; i < userHdr.numOfFinger * 2; i++)
        {
            templateBuf = new byte[userHdr.numOfFinger * 2 * BS_TEMPLATE_SIZE * bufPos];
            result = BSSDK.BS_ScanTemplate(m_Handle, templateBuf);
            bufPos += BS_TEMPLATE_SIZE;
        }
    

    此代码不是按顺序存储BS_ScanTemplate的结果,而是通过重新分配数组来抛弃前面每个调用的结果。也许你想要这样的东西:

        byte[] templateBuf = new byte[userHdr.numOfFinger * 2 * BS_TEMPLATE_SIZE];
        for (int i = 0, bufPos = 0; i < userHdr.numOfFinger * 2; i++)
        {
            byte[] singleBuf = new byte[BS_TEMPLATE_SIZE];
            result = BSSDK.BS_ScanTemplate(m_Handle, singleBuf);
            Array.Copy(singleBuf, 0, templateBuf, bufPos, singleBuf.Length);
            bufPos += singleBuf.Length;
        }
    
  2. c ++代码

    for( int i = 0; i < userHeader.numOfFinger; i++ )
    {
        userHeader.duress[i] = 0; // no duress finger
    }
    

    c#代码确实:

        userHdr.duressMask = 0; // no duress finger
    

    这完全不同。

  3. c ++代码确实:

    for( int i = 0; i < userHeader.numOfFinger * 2; i++ )
    {
        if( i % 2 == 0 )
        {
            userHeader.fingerChecksum[i/2] = 0;
        }
        unsigned char* templateData = templateBuf + i * BS_TEMPLATE_SIZE;
        for( int j = 0; j < BS_TEMPLATE_SIZE; j++ )
        {
            userHeader.fingerChecksum[i/2] += templateData[j];
        }
    }
    

    c#代码确实:

        for (int i = 0; i < userHdr.numOfFinger * 2; i++)
        {
            if (i % 2 == 0)
            {
                userHdr.checksum[i / 2] = 0;
            }
            byte[] templateData = templateBuf;
            for (int j = 0; j < 2000 - 1; j++)
            {
                userHdr.checksum[i / 2] += templateData[j];
            }
        }
    

    正如您所看到的,c ++代码循环次数是c#代码的两倍。 c#代码可能应该是:

        for (int i = 0; i < userHdr.numOfFinger; i++)
        {
            if (i % 2 == 0)
            {
                userHdr.checksum[i / 2] = 0;
            }
            for (int j = 0; j < BS_TEMPLATE_SIZE; j++)
            {
                userHdr.checksum[i / 2] += templateBuf[i * BS_TEMPLATE_SIZE + j];
            }
        }
    
  4. 您没有在pastie中显示对BS_EnrollUserBioStation2的c ++通话,因此无法与c#通话进行比较。

  5. userHdr.checksum = new ushort[] { 0 };看起来不对。不应该像userHdr.checksum = new ushort[userHdr.numOfFinger];

  6. 那样

    因此,我建议如下:

    按如下方式更新BSUserHdrEx

        public const int BS_MAX_NAME_LEN = 32;
        public const int BS_MAX_PASSWORD_LEN = 16;
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct BSUserHdrEx
        {
            public static BSUserHdrEx CreateDefaultBSUserHdrEx()
            {
                var userHdr = new BSUserHdrEx();
                userHdr.name = new byte[BSSDK.BS_MAX_NAME_LEN + 1];
                userHdr.department = new byte[BSSDK.BS_MAX_NAME_LEN + 1];
                userHdr.password = new byte[BSSDK.BS_MAX_PASSWORD_LEN];
                userHdr.checksum = new ushort[5];
                return userHdr;
            }
    
            public uint ID;
            public ushort reserved1;
            public ushort adminLevel;
            public ushort securityLevel;
            public ushort statusMask; // internally used by BioStation
            public uint accessGroupMask;
    
            //char name[BS_MAX_NAME_LEN + 1];
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = BSSDK.BS_MAX_NAME_LEN + 1)]
            public byte[] name;
    
            //char department[BS_MAX_NAME_LEN + 1];
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = BSSDK.BS_MAX_NAME_LEN + 1)]
            public byte[] department;
    
            // char password[BS_MAX_PASSWORD_LEN + 1];
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = BSSDK.BS_MAX_PASSWORD_LEN + 1)]
            public byte[] password;
    
            public ushort numOfFinger;
            public ushort duressMask;
    
            //public ushort checksum[5];
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            public ushort[] checksum;
    
            public ushort authMode;
            public ushort authLimitCount; // 0 for no limit
            public ushort reserved;
            public ushort timedAntiPassback; // in minutes. 0 for no limit
            public uint cardID; // 0 for not used
            public bool bypassCard;
            public bool disabled;
            public uint expireDateTime;
            public uint customID; //card Custom ID
            public int version; // card Info Version
            public uint startDateTime;
        };
    

    按如下方式更新btngetUserInfo_Click

        private void btngetUserInfo_Click(object sender, EventArgs e)
        {
            int result;
    
            BSSDK.BSUserHdrEx userHdr = BSSDK.BSUserHdrEx.CreateDefaultBSUserHdrEx();
            userHdr.ID = 2; // 0 cannot be assigned as a user ID
            userHdr.startDateTime = 0; // no check for start date
            userHdr.expireDateTime = 0; // no check for expiry date
            userHdr.adminLevel = BSSDK.BS_USER_NORMAL;
            userHdr.securityLevel = BSSDK.BS_USER_SECURITY_DEFAULT;
            userHdr.authMode = BSSDK.BS_AUTH_MODE_DISABLED; // use the authentication mode of the device
            userHdr.accessGroupMask = 0xffff0201; // a member of Group 1 and Group 2;
            Encoding.UTF8.GetBytes("Madman").CopyTo(userHdr.name, 0);
            Encoding.UTF8.GetBytes("INC").CopyTo(userHdr.department, 0);
            Encoding.UTF8.GetBytes("").CopyTo(userHdr.password, 0);
            userHdr.password = Encoding.UTF8.GetBytes("");  // no password is enrolled. Password should be longer than 4 bytes.
            userHdr.numOfFinger = 2;
            byte[] templateBuf = new byte[userHdr.numOfFinger * 2 * BSSDK.BS_TEMPLATE_SIZE];
            for (int i = 0, bufPos = 0; i < userHdr.numOfFinger * 2; i++)
            {
                byte[] singleBuf = new byte[BSSDK.BS_TEMPLATE_SIZE];
                result = BSSDK.BS_ScanTemplate(m_Handle, singleBuf);
                Array.Copy(singleBuf, 0, templateBuf, bufPos, singleBuf.Length);
                bufPos += singleBuf.Length;
            }
            userHdr.duressMask = 0; // no duress finger
    
            for (int i = 0; i < userHdr.numOfFinger * 2; i++)
            {
                if (i % 2 == 0)
                {
                    userHdr.checksum[i / 2] = 0;
                }
                // byte[] templateData = templateBuf;
                for (int j = 0; j < BSSDK.BS_TEMPLATE_SIZE; j++)
                {
                    userHdr.checksum[i / 2] += templateBuf[i * BSSDK.BS_TEMPLATE_SIZE + j];
                }
            }
    
            // enroll the user
            result = BSSDK.BS_EnrollUserBioStation2(m_Handle, ref userHdr, templateBuf);
            if (result == (int)BSSDK.BS_RET_CODE.BS_SUCCESS)
            {
                MessageBox.Show("user " + userHdr.name.ToString() + " enrolled");
            }
    

    <强>更新

    您正在编组的结构是BSUserHdrExBS_EnrollUserBioStation2不以此为参数。 BS_EnrollUserBioStation2BS2UserHdr为参数(来源:&#34; BioStar SDK手册V1.8.pdf&#34;。)BSUserHdrEx是{{1}的参数}}。 (第129页)。

    • BS_EnrollUserEx&#34;将用户注册到BioStation。每个用户最多可以注册5个手指。&#34;
    • BS_EnrollUserEx&#34;将用户注册到BioStation T2。每位用户最多10个手指。&#34;

    您需要切换到以前的功能,或使用后一种数据结构。